I'm using kohana 3.2. and I'm having some trouble getting this new model to work..
There's the model: Model_User_Unavailability which works fine and there's the model Model_User_Unavailability_Status which doesn't.
The problem isn't finding the model, it's using it. I can make a status using: ORM::factory('user_unavailability_status'); and it works just fine, but when I want to add the status to the unavailability class it won't work and I'm getting the following exception:
Incorrect table name '' [ INSERT INTO `` (`user_unavailability_id`, `status_id`) VALUES ('670', NULL) ]
The classes look like this:
class Model_User_Unavailability extends ORM
{
protected $_belongs_to = array(
'user' => array(),
);
protected $_table_name = 'user_unavailability';
protected $_has_many = array(
'status' => array(
'model' => 'User_Unavailability_Status',
'foreign_key' => 'user_unavailability_id'
)
);
...etc
class Model_User_Unavailability_Status extends ORM
{
protected $_table_name = 'user_unavailability_status';
protected $_belongs_to = array(
'user_unavailability' => array(
'foreign_key' => 'user_unavailability_id',
'model' => 'user_unavailability'
)
);
etc...
Now the exception appears when I try the following:
$db = $user->unavailable->where('id', '=', $id)->find(); // Returns User_Unavailability object
//... do some other stuf...
$db->save();
if($db->loaded())
{
$status = ORM::factory('user_unavailability_status');
$status->status = 'requested';
$status->responder_id = 1;
$db->add('status',$status);
}
As you can see in the exception earlier it won't use the specified table name. However, when I remove the $_table_name variable from the status class I get the following error:
Table 'urenregistratie.user_unavailability_statuses' doesn't exist [ SHOW FULL COLUMNS FROM `user_unavailability_statuses` ]
As you can see it does find the model, but won't find the database table. So my question here is, what's going on here? I guess I'm missing something but I don't know what...
Same happens when i use the $this->_table_names_plural = false in the status model.
So... any suggestions / ideas?
Edit:
It seems to work when I change the $db->add('status',$status); line to:
$status->user_unavailability_id = $db->id;
$status->save();
Not pretty though and still wondering what's preventing me from using the add function.
add() is used in has_many "through" relationships.
In your case you have already written the correct way:
$status->user_unavailability_id = $db->id;
$status->save();
Related
I am having trouble using updateOrCreate.
The below code is SUCCESSFULLY creating a new row; however when it comes to updating an existing row it doesn't work at all!
comm_helpful::updateOrCreate(
['ID' => 1],
['time' => 3000]
);
This works exactly as expected:
comm_helpful::where('ID', 1)->update(['time' => 3000]);
I've stripped the examples above back to bare minimums (which I did as part of debugging) and it's still not working!!
I have a similar problem.
My model had:
protected $fillable = ['user_x_cliente_id','internet_cliente_id'];
The status has 0.
$habilita = leilao_habs::updateOrCreate(
[
'user_x_cliente_id' => $user_x_cliente->id,
'internet_cliente_id' => $int_cli->id
],
['status' => 1]
);
dd($habilita);
After execute the updateOrCreate , the status still 0 and No get MassAssignmentException error.
The solution was change the model adding the status to protected $fillable:
protected $fillable = ['user_x_cliente_id','internet_cliente_id','status'];
Now the updateOrCreate works changing the status.
Ok, after almost completely pulling my hair out; I found the problem where Eloquent is setting:
protected $primaryKey = 'id';
which is used on the update method and returned by getKeyName().
protected function setKeysForSaveQuery(Builder $query)
{
$query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
return $query;
}
I then realised my 'id' on the tale was uppercase and not lower case!
I guess that means my answer is that I need to ensure I am using lowercase 'id' for the primary key or overriding it on the Model
protected $primaryKey = 'ID';
I'm performing a simple insert which I've done many times without any issues and for some odd reason it's not working and I get this error message:
error: {type: "ErrorException", message: "Array to string conversion",…}
file: "C:\wamp\www\studentreg2\vendor\laravel\framework\src\Illuminate\Database\Grammar.php"
line: 33
message: "Array to string conversion"
type: "ErrorException"
Here's my code:
$advisorCheck = AdvisorCheck::create([
'status' => Input::get('status'),
'application_id' => Input::get('id'),
'user_id' => Auth::id()
]);
The migration for the advisor_check table which AdvisorCheck model uses seems fine, all foreign keys are unsigned and show the relations correctly in phpmyadmin, all values from the Input::get are strings, the model has the correct fields set as fillable (status, application_id, user_id).
I've even tried doing this in php artisan tinker like this:
AdvisorCheck::create([ 'status' => 'returned', 'application_id' => '3', 'user_id' => '4']);
and I get this response:
Array to string conversion
I've also tried this method and get the same error:
$advisorCheck = new AdvisorCheck;
$advisorCheck->status = Input::get('status');
$advisorCheck->application_id = Input::get('id');
$advisorCheck->user_id = Auth::id();
$advisorCheck->save();
Model code:
<?php
class AdvisorCheck extends \Eloquent {
protected $fillable = ['status', 'application_id', 'user_id'];
protected $table = ['advisor_check'];
}
If you need to see more code please ask.
Many thanks to anyone who can help!
As you can see in the example that's shown in the Laravel docs the table property is a string and not an array
protected $table = 'advisor_check';
Which makes total sense if you think about it, since Eloquent models don't support multiple tables natively.
$table should be a string not array
<?php
class AdvisorCheck extends \Eloquent {
protected $fillable = ['status', 'application_id', 'user_id'];
protected $table = 'advisor_check';
}
if we give table name in laravel model like array:
protected $table = ['thoughts'];
then it will generate error.
so you should give table name as string like :
protected $table = 'thoughts';
I have a Seeder for different models and one of them is giving me the following error when I try to artisan db:seed
PHP Fatal error: Call to undefined method Illuminate\Events\Dispatcher::create() in C:\www\site\bootstrap\compiled.php on line 3155
Here's Event.php, the model that seems to cause the problem:
<?php
class Event extends Eloquent {
protected $fillable = array('name', 'played_on');
protected $table = 'events';
// RELATIONSHIPS ----------------------------
// Event has many Decks
public function decks() {
return $this->belongsToMany('Deck', 'decks_events', 'event_id', 'deck_id');
}
}
Note: I added the protected $table = 'events' to try and see if this was causing the problem, I don't think it's required. Here is part of the Seeder. The Deck part works fine (in fact, I do see the 'Added some cards to some decks' message because it crashes)
// Decks
$deck_1 = Deck::create(array(
'meta' => 'U/W Control',
'player' => 'Cookie Monster'
));
$deck_2 = Deck::create(array(
'meta' => 'RDW',
'player' => 'Suzy Waterbottle'
));
// All 3 cards in Deck 1
$card_1->decks()->attach($deck_1->id);
$card_2->decks()->attach($deck_1->id);
$card_3->decks()->attach($deck_1->id);
// 2 cards in Deck 2
$card_1->decks()->attach($deck_2->id);
$card_2->decks()->attach($deck_2->id);
$this->command->info('Added some cards to some decks');
// Events
$event_1 = Event::create(array(
'name' => 'Super Duper Tourney',
'played_on' => '07/05/2014'
));
$deck_1->events()->attach($event_1->id);
$deck_2->events()->attach($event_1->id);
$this->command->info('Added decks to the event');
This leads me to believe that something wrong happens on the $event_1 = Event::create line but I can't figure out what as it looks exactly like the code used for $deck_1... and $deck_2...
Event is a "reserved" word in Laravel. You may have to change it or namespace your class.
So, instead of your Event model class, it is using Laravel Event, which is Illuminate\Events\Dispatcher.
It is actually an Alias we have on app/config/app.php.
Namespacing it:
<?php namespace App;
use Eloquent;
class Event extends Eloquent {
...
}
Using it namespaced:
<?php
use App\Event;
class Whatever {
$event_1 = Event::create(array(
'name' => 'Super Duper Tourney',
'played_on' => '07/05/2014'
));
}
You may need to
composer dumpautoload
To refresh your autoloaded namespaces and classes.
I'm starting a cakephp app, I've never used it in real world so I'm a bit confused how HABTM works, even though I read the documentation I couldn't get even the $this->User->Subscription and didn't see any extra object dumped
What I want is to create a HATBM between users and subscriptions
so I created three tables (users,subscriptions,users_subscribers)
Then in my User.php model I did this
var $hasAndBelongsToMany =
array(
'Subscription' =>
array('className'=>'Subscription',
'joinTable' => 'users_subscribers',
'foreignKey' => 'user_id',
'associationForeignKey' => 'subscription_id',
'unique' => true,
)
);
SUbscription.php
var $hasAndBelongsToMany = array(
'User'=>array('className'=>'User',
'joinTable' => 'users_subscribers',
'foreignKey' => 'subscription_id',
'associationForeignKey' => 'user_id',
'unique' => true));
Even with the tags example and following it, I cannot get the relation set, I also added the line <?php echo $this->element('sql_dump'); ?> to see if its running which it isn't...
Could anyone guide me how exactly you get HATBM to work, what else do I need to verify?
Full code:
pages_controller.php
http://sao.pastebin.com/PWQMhE2z
User model:
http://sao.pastebin.com/PWqwAj1v
Subscription model:
http://sao.pastebin.com/MfVFR4Kw
subscriptions SCHEMA:
http://sao.pastebin.com/mLRcEp1c
User SCHEMA:
http://sao.pastebin.com/UeTRHh3u
users_subscriptions SCHEMA:
http://sao.pastebin.com/4UeSDZte
The simplest and fastest way to get this working is by following CakePHP's rule of configuration over customization.
This means following the CakePHP conventions unless you have a very good reason not to.
I'd strongly recommend starting with a basic setup that you know works, and then modifying that if you need to. Here's a quick and easy way to get up and running.
The Database Tables
Start with three database tables: users, subscriptions and subscriptions_users. The schemas you already have are ok, but I'd make a couple modifications to make sure things go smoothly:
Add a name or title column to the users table. Either that, or you'll have to add the $displayField property to your User model. If you don't do this you'll miss out on some of the "automagic" that CakePHP provides. More info on $displayField
Change the join table's name to subscriptions_users. This is the CakePHP convention and there's no reason not to save yourself the time and worry of following it. :-)
Use the following schema for the join table:
CREATE TABLE subscriptions_users (
subscription_id int(11) NOT NULL,
user_id int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Note that there aren't any keys defined. From the CakePHP manual: "To avoid any issues - don't define a combined primary key for these two fields, if your application requires it you can define a unique index."
The Models
Try to keep your code clean. There are a lot of sensible defaults implemented in CakePHP and there's no point in defining them when they're already defined.
The following models should work for you:
user.php
<?php
class User extends AppModel {
var $hasAndBelongsToMany = array('Subscription');
}
?>
subscription.php
<?php
class User extends AppModel {
var $hasAndBelongsToMany = array('User');
}
?>
Pretty simple. Just be sure your model files are named correctly: user.php and subscription.php, all lowercase.
Also, note that you don't have to set any of the relationship options (className, joinTable, etc.) unless they need to be something besides the default. Ninety percent of the time the defaults should serve you just fine.
You should be up and running now. You can make sure the model objects are being loaded and are accessible in your controllers like this:
users_controller.php
<?php
class UsersController extends AppController {
var $name = 'Users';
function index() {
$this->autoRender = false;
var_dump(is_object($this->User));
var_dump(is_object($this->User->Subscription));
}
}
?>
subscriptions_controller.php
<?php
class SubscriptionsController extends AppController {
var $name = 'Subscriptions';
function index() {
$this->autoRender = false;
var_dump(is_object($this->Subscription));
var_dump(is_object($this->Subscription->User));
}
}
?>
The output of /users and /subscriptions should both be bool(true) bool(true).
You can see the full models by doing pr($this->User);.
Deleting records
If you delete a single record using, for example, $this->User->delete($user_id), all the records in the join table with that user ID will automatically be deleted as well.
If you want to delete a single record from a HABTM join table, without deleting the records that it links to, in effect, "unjoining" the two records, you can do it through the SubscriptionsUser model. This is a model that is created on the fly whenever there's a HABTM relationship.
See here for an example: CakePHP hasAndBelongsToMany (HABTM) Delete Joining Record
I did a test app with a basic schema and I get all the relations right. I suspect your woes have to do with the fact that you did $uses = array('User', 'Subscription');Why don't you try with $uses = $uses = array('User'); and then try
$this->User->find('all');
$this->User->Subscription->find('all');
You also need to define the same HABTM relation in your Subscription.php model. If I recall correctly, CakePHP internally fetches some of the required information from the other side's HABTM configuration.
I always use two "hasMany" relations and one "belongsTo" relation to get the HABTM effect in CakePHP with more control.
Try this:
User model (user.php)
class User extends AppModel {
public $name = 'User';
public $actsAs = array('Containable');
public $hasMany = array('UserSubscription');
}
Subscription model (subscription.php)
class Subscription extends AppModel {
public $name = 'Subscription';
public $actsAs = array('Containable');
public $hasMany = array('UserSubscription');
}
UserSubscription model (user_subscription.php)
class UserSubscription extends AppModel {
public $name = 'UserSubscription';
public $belongsTo = array('User','Subscription');
}
pages/home action (pages_controller.php)
public function home() {
$data = array(
'User' => array(
'id' => 1, 'user_email' => 'allenskd#gmail.com', 'user_password' => 'fdfdkert', 'user_salt' => 'haha', 'user_displayname' => 'David'
),
'UserSubscription' => array(
'user_id' => '1', 'subscription_id' => '1'
),
'Subscription' => array(
'id' => 1, 'title' => 'My first plan', 'price' => '30.00', 'subscriber_count' => '1'
),
);
$this->Subscription->save($data);
$this->User->saveAll($data);
$test = $this->User->find('all', array('contain' => array('UserSubscription' => array('Subscription'))));
pr($test);
}
I have the following tables in the database:
teams:
id
name
matches:
id
team1_id
team2_id
I've defined the following ORM models in my Kohana v2.3.4 application:
class Match_Model extends ORM {
protected $belongs_to = array('team1_id' => 'team', 'team2_id' => 'team');
}
class Team_Model extends ORM {
protected $has_many = array('matches');
}
The following code in a controller:
$match = ORM::factory('match',1);
echo $match->team1_id->name; /* <-- */
Is throwing the following error on the linke marked with /* <--- */:
Trying to get property of non-object
The framework is yielding the value of the foreign key instead of a reference to a Match_Model instance as it should (giving the has_many and belongs_to properties stated).
Am I missing something?
Note: Just in case, I've added the irregular plural 'match' => 'matches' in application/config/inflector.php
SOLVED! The Kohana community gave me the answer:
The correct value for the $belongs_to property is:
class Match_Model extends ORM {
protected $belongs_to = array('team1' => 'team', 'team2' => 'team');
}
The documentation states it:
class Blog_Post_Model extends ORM {
protected $belongs_to = array('author' => 'user', 'editor' => 'user');
}
The blog_posts database table would
have 2 columns now,
blog_posts.author_id and
blog_posts.editor_id, and both would
have values that exist in users.id.
It seems that I've missed that line, :)