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.
Related
We have a table consignments which is having big data . so to keep our query quick we archive our old data to another table which is archive_consignments but in our consignment model I want that when I use eloquent like this
Consignment::find(1)
first it should try to get data from consignments table if it didn't found then it go to archive_consignments
is that possible to define this thing in eloquent model of Consignment
<?php
namespace App\Models\Admin;
use Illuminate\Database\Eloquent\Model;
use Nicolaslopezj\Searchable\SearchableTrait;
use Staudenmeir\EloquentHasManyDeep\HasRelationships;
use Laravel\Scout\Searchable;
class Consignment extends Model
{
// use SearchableTrait;
use Searchable;
use HasRelationships;
protected $table = 'consignments';
// following function to search by id(laravel scout)
public function getScoutKey()
{
return $this->id;
}
}
you could write using query builder
if(data not found in consignments )
{
$data = \DB::table('archive_consignments')->here your conditiion to find data
}
hope this will be useful.
What I would go with is to make ArchivedConsignment Model
Also I would make a function inside Repository that would be named something like queryConsignment and pass all my conditions as array for ex.
[ 'where' => ['column' => 'name', 'value' => 'someName'], 'whereIn' => ['column' => 'name', 'value' =>['bla','bla'] ]
Inside queryConsignment I would firstly call
$query = Consignment::newQuery()
after that I would apply all those conditions using a loop.
foreach($conditons as $method => $conditon){
$query->$method($condition['column'], $condition['value');
}
$data = $query->first();
At the end if there is no entry inside Consignment I would do the same with ArchivedConsignment
I am a Laravel newbie. I want to seed my database. When I run the seed command I get an exception
[Illuminate\Database\Eloquent\MassAssignmentException]
username
db:seed [--class[="..."]] [--database[="..."]]
What am I doing wrong. The command I use is:
php artisan db:seed --class="UsersTableSeeder"
My seed class is as follows:
class UsersTableSeeder extends Seeder {
public function run()
{
User::truncate();
User::create([
'username' => 'PaulSheer',
'email' => 'psheer#rute.co.za',
'password' => '45678'
]);
User::create([
'username' => 'Stevo',
'email' => 'steve#rute.co.za',
'password' => '45678'
]);
}
}
Read this section of Laravel doc : http://laravel.com/docs/eloquent#mass-assignment
Laravel provides by default a protection against mass assignment security issues. That's why you have to manually define which fields could be "mass assigned" :
class User extends Model
{
protected $fillable = ['username', 'email', 'password'];
}
Warning : be careful when you allow the mass assignment of critical fields like password or role. It could lead to a security issue because users could be able to update this fields values when you don't want to.
I am using Laravel 4.2.
the error you are seeing
[Illuminate\Database\Eloquent\MassAssignmentException]
username
indeed is because the database is protected from filling en masse, which is what you are doing when you are executing a seeder. However, in my opinion, it's not necessary (and might be insecure) to declare which fields should be fillable in your model if you only need to execute a seeder.
In your seeding folder you have the DatabaseSeeder class:
class DatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Eloquent::unguard();
//$this->call('UserTableSeeder');
}
}
This class acts as a facade, listing all the seeders that need to be executed. If you call the UsersTableSeeder seeder manually through artisan, like you did with the php artisan db:seed --class="UsersTableSeeder" command, you bypass this DatabaseSeeder class.
In this DatabaseSeeder class the command Eloquent::unguard(); allows temporary mass assignment on all tables, which is exactly what you need when you are seeding a database. This unguard method is only executed when you run the php aristan db:seed command, hence it being temporary as opposed to making the fields fillable in your model (as stated in the accepted and other answers).
All you need to do is add the $this->call('UsersTableSeeder'); to the run method in the DatabaseSeeder class and run php aristan db:seed in your CLI which by default will execute DatabaseSeeder.
Also note that you are using a plural classname Users, while Laraval uses the the singular form User. If you decide to change your class to the conventional singular form, you can simply uncomment the //$this->call('UserTableSeeder'); which has already been assigned but commented out by default in the DatabaseSeeder class.
To make all fields fillable, just declare on your class:
protected $guarded = array();
This will enable you to call fill method without declare each field.
Just add Eloquent::unguard(); in the top of the run method when you do a seed, no need to create an $fillable array in all the models you have to seed.
Normally this is already specified in the DatabaseSeeder class. However because you're calling the UsersTableSeeder directly:
php artisan db:seed --class="UsersTableSeeder"
Eloquent::unguard(); isn't being called and gives the error.
I used this and have no problem:
protected $guarded=[];
I was getting the MassAssignmentException when I have extends my model like this.
class Upload extends Eloquent {
}
I was trying to insert array like this
Upload::create($array);//$array was data to insert.
Issue has been resolve when I created Upload Model as
class Upload extends Eloquent {
protected $guarded = array(); // Important
}
Reference https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670
User proper model in your controller file.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
if you have table and fields on database you can simply use this command :
php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE
This is not a good way when you want to seeding database.
Use faker instead of hard coding, and before all this maybe it's better to truncate tables.
Consider this example :
// Truncate table.
DB::table('users')->truncate();
// Create an instance of faker.
$faker = Faker::create();
// define an array for fake data.
$users = [];
// Make an array of 500 users with faker.
foreach (range(1, 500) as $index)
{
$users[] = [
'group_id' => rand(1, 3),
'name' => $faker->name,
'company' => $faker->company,
'email' => $faker->email,
'phone' => $faker->phoneNumber,
'address' => "{$faker->streetName} {$faker->postCode} {$faker->city}",
'about' => $faker->sentence($nbWords = 20, $variableNbWords = true),
'created_at' => new DateTime,
'updated_at' => new DateTime,
];
}
// Insert into database.
DB::table('users')->insert($users);
Use the fillable to tell laravel which fields can be filled using an array.
By default, Laravel does not allow database fields to be updated via an array
Protected $fillable=array('Fields you want to fill using array');
The opposite of fillable is guardable.
If you use the OOP method of inserting, you don't need to worry about mass-action/fillable properties:
$user = new User;
$user->username = 'Stevo';
$user->email = 'steve#rute.co.za';
$user->password = '45678';
$user->save();
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();
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, :)