Custom relation names in models generated from DB - doctrine

I'm generating my models from database and I get something like this:
public function setUp()
{
parent::setUp();
$this->hasOne('Articles', array(
'local' => 'article_id',
'foreign' => 'id'));
$this->hasOne('Users', array(
'local' => 'voter_id',
'foreign' => 'id'));
$this->hasOne('Users as Users_4', array(
'local' => 'author_id',
'foreign' => 'id'));
}
Is there any way to tell doctrine, what should be the names of relationships. For example to get something like this:
public function setUp()
{
$this->hasOne('Articles', array(
'local' => 'article_id',
'foreign' => 'id'));
$this->hasOne('Users as Voter', array(
'local' => 'voter_id',
'foreign' => 'id'));
$this->hasOne('Users as Author', array(
'local' => 'author_id',
'foreign' => 'id'));
}
I know it is possible when you generate models from YAML files or write them from scratch, but is it possible when you generate models from DB?

There's no way to do what you are asking. As an alternative, you could generate a YAML file from the db, add the relation names there, and then generate your models from the YAML file.

Related

Laravel validator's equivalent of isset()

In my FormRequest I need to validate, if selected category is actually present in the categories array.
I solved my problem with withValidator method, where I manually check if the category is present.
However, I feel like there must be a nicer way of doing this. I went over validation documentation, but could not find my fit.
Has anyone tackled this problem, or do you have an idea how to do this better?
Thank you.
class StoreWarehouseItemRequest extends FormRequest
{
public function rules()
{
return [
'name' => 'required',
'category' => 'required|integer',
'specification' => 'nullable|string',
'recipient' => 'nullable|string',
'unit' => 'nullable|string',
'sellers_code' => 'nullable|string',
'note' => 'nullable|string',
];
}
public function withValidator(Validator $validator)
{
$cat = $validator->getData()['category'];
$cats = WarehouseItem::CATEGORIES;
$validator->after(
function ($validator) use ($cat, $cats) {
if (!isset($cats[$cat])) {
$validator->errors()->add('category', 'Kategória musí byť vybraná zo zoznamu.');
}
}
);
}
}
You could use Laravel's in:foo,bar validator.
return [
'name' => 'required',
'category' => ['required', 'integer', Rule::in(WarehouseItem::CATEGORIES)],
'specification' => 'nullable|string',
'recipient' => 'nullable|string',
'unit' => 'nullable|string',
'sellers_code' => 'nullable|string',
'note' => 'nullable|string',
];
Additionally, if you are looking if the key exists in the WarehouseItem::CATEGORIES array, you can do array_flip(WarehouseItem::CATEGORIES) on it.

How is it possible to retrieve the id of a Model right after it was created in the same controller function?

Let me show you my code, and place comments for you guys to better understand:
$homework = new Homework([ // I create Homework (And I indeed want to get the ID of the one that was just created).
'subject_id' => $request->subject_id,
'user_id' => auth()->user()->id,
'title' => $request->name,
'image' => $path,
'progress' => $request->progress,
'description' => $request->description,
'duedate' => $request->date
]);
$homework->save(); // I save it
$homeworkid = Homework::where('id', $id)->first(); // I try to retrieve it, but I'm not sure how to get it as I need to define `$id`.
$progress = newProgress([
'user_id' => auth()->user()->id,
'homework_id' => $homeworkid, // I need this for the relationship to work.
'title' => 'Initial Progress',
'description' => 'This progress is auto-generated when you create an assignment',
'username' => auth()->user()->name,
'progress' => $homeworkid->progress
]);
$progress->save(); // I save the progress
Well, as you saw, I'm trying to retrieve the ID of Homework right after it was created, but I'm not sure how to define $id in order to get it.
There is no need to instantiate a new model and saving it if your are not doing anything between instantiating and saving, you can use the create method instead:
$homework = Homework::create([
'subject_id' => $request->subject_id,
'user_id' => auth()->user()->id,
'title' => $request->name,
'image' => $path,
'progress' => $request->progress,
'description' => $request->description,
'duedate' => $request->date
]);
$homework->id; // get the id
After saving / creating the model you can access the id like you normally would:
$homework->id
What you then could do is setup the relationships between your models so you can do the following after creating a new homework:
$homework->newProgress()->create([
'user_id' => auth()->user()->id,
'title' => 'Initial Progress',
'description' => 'This progress is auto-generated when you create an assignment',
'username' => auth()->user()->name,
'progress' => $homework->progress
]);
This way you don't have to pass the homework id when creating a new newProgress, laravel will pass it automatically for you.
This is very simple for you. No need to complex it.
$homework->save(); // I save it
After this line just use only
$progress = newProgress([
'user_id' => auth()->user()->id,
'homework_id' => $homework->id, // I need this for the relationship to work.
'title' => 'Initial Progress',
'description' => 'This progress is auto-generated when you create an assignment',
'username' => auth()->user()->name,
'progress' => $homework->progress
]);
You don't no need this line of code
$homeworkid = Homework::where('id', $id)->first(); // I try to retrieve it, but I'm not sure how to get it as I need to define `$id`.
$data = $homework->save();
Get the ID this way: $data->id

How can I maintain foreign keys when seeding database with Faker?

Below is my model factory.
$factory->define(App\Business::class, function (Faker\Generator $faker){
return [
'name' => $faker->bs,
'slug' => $faker->slug,
'address' => $faker->streetAddress,
'phone_no' => $faker->phoneNumber,
'mobile_no' => $faker->phoneNumber,
'email' => $faker->companyEmail,
'website' => $faker->domainName,
'latitude' => $faker->latitude,
'longitude' => $faker->longitude,
'location' => $faker->city,
'business_days_from' => $faker->dayOfWeek,
'business_days_to' => $faker->dayOfWeek,
'description' => $faker->text,
'user_id' => $faker->factory(App\User::class),
];
});
and This my database seeder class
class DatabaseSeeder extends Seeder
{
public function run()
{
factory(App\Business::class, 300)->create();
}
}
But when I execute php artisan db:seed ...it does not work..
What should be the workaround here..any help would be appreciated..
you can get all ids using pluck (lists is depricated for laravel >= 5.2)
$userIds = User::all()->pluck('id')->toArray();
and get a random id for FK column:
'user_id' => $faker->randomElement($userIds)
You may also attach relationships to models using Closure attributes in your factory definitions.
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
return factory(App\User::class)->create()->id;
}
I just found the workaround .. I replaced
'user_id' => $faker->factory(App\User::class),
with
'user_id' => $faker->randomElement(User::lists('id')->toArray()),
and that solves the problem for now..

Cakephp data does'nt save in multiple models association

I am trying to save data in multiple models association but the same is not saving at all. I have all set up correctly i.e. data from form is ok (debug shows all) and find also fetches the data but couldn't understand where the problem lies. My code is follows as:
Controller:
if($url == "expense_reports") { $this->set('tab_content','Invoice - Expense Reports'); $this->render('/job/invoice2');
if($this->request->is('post'))
{//debug($this->data);
$this->Event->Invoice->Expense->save($this->data); }
}
Models (Associations):
Event
public $belongsTo = array(
'EventType' => array(
'className' => 'AgencyCalendar.EventType',
'foreignKey' => 'event_type_id'
)
);
public $hasMany = array(
'Invoice' => array(
'className' => 'AgencyCalendar.Invoice',
'foreignKey' => 'event_id',
'dependent' => false
)
);
Invoice
public $belongsTo = array(
'Event' => array(
'className' => 'AgencyCalendar.Event',
'foreignKey' => 'event_id'
)
);
public $hasMany = array(
'Expense' => array(
'className' => 'AgencyCalendar.Expense',
'foreignKey' => 'invoice_id',
'dependent' => false
)
);
Expense
public $belongsTo = array(
'Invoice' => array(
'className' => 'AgencyCalendar.Invoice',
'foreignKey' => 'invoice_id'
)
);
I am also not getting any sql dump in my view for this particular action to find out what is going on actually. Also how can I save multiple rows which would be generated from my expense view. My expense view is custom url so might be it would be a cause of not showing the sql dump or is this also a cause of not saving the data at all? Please let me know what I am doing wrong?
I believe what you are looking for is saveAll. (http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveall-array-data-null-array-options-array)
$this->Event->saveAll($this->data);
This will work as long as you have:
- the model relationships setup correctly
- the correct array attributes in $this->data

Table creaction on doctrine migration for custom behavior

I've created custom doctrine(1.2) behavior which should create tables for models (very simmilar to i18n behavior). I see this tables in schema.sql, and if i execute it everything is fine, but this is no such tables if my migrations diff (doctrine:generate-migrations-diff).
What i'm doing wrong?
class DescriptionableGenerator extends Doctrine_Record_Generator
{
protected $_options = array(
'className' => '%CLASS%Description',
'tableName' => '%TABLE%_description',
'fields' => array(),
'generateFiles' => false,
'table' => false,
'pluginTable' => false,
'children' => array(),
'options' => array(),
'cascadeDelete' => true,
'appLevelDelete' => false
);
public function __construct(array $options = array())
{
$this->_options = Doctrine_Lib::arrayDeepMerge($this->_options, $options);
}
public function buildRelation()
{
$this->buildForeignRelation('Descriptions');
$this->buildLocalRelation();
}
public function setTableDefinition()
{
$this->hasColumn('lang', 'char', '2', array('notnull' => true));
$this->hasColumn('field', 'string', '255', array('notnull' => true));
$this->hasColumn('title', 'string', '255', array('notnull' => true));
$this->hasColumn('description', 'clob');
$this->hasColumn('compulsory', 'boolean', 1, array('notnull' => true, 'default' => 0));
$this->addListener(new DescriptionableListener());
}
}
Solved!
Problem appears due to command "php symfony doctrine:build-model".
So, if you have the same problem you should:
Remove your behavior from schema.
Execute "php symfony doctrine:build-model".
Add your behavior to schema.
Run "php symfony doctrine:generate-migrations-diff".
Chears! %)

Resources