Skip to content

Make model relationship creates filtered by fillable array #2846

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

vlakarados
Copy link

Currently, when creating instances in a model relationship, attribute $fillable = array(...) of the relationship is ignored. As stated by the comment, it's done so to allow foreign keys to be automatically set. Now it allows us to do this as it fills attributes beforehand with fill() and then sets merged raw attributes filtered by fill() with foreign keys, thus, we may now do things like

$contactData = [
    'type' => 'qwe',
    'value' => 'qwe',
    'foo' => 999
];
$client = Client::find(1);
$client->contacts()->create($contactData);

which is much more clean than

$contactData = [
    'type' => 'qwe',
    'value' => 'qwe',
    'foo' => 999
];

$client = Client::find(1);
$clientContact = ClientContact::create($contactData);
$client->contacts()->save($clientContact);

In the examples above 'foo' database table column does not exist and because of that we get the SQL error if we don't fill().

$instance = $this->related->newInstance();

$instance->setRawAttributes(array_merge($attributes, $foreign));
$instance->fill($attributes);
$instance->setRawAttributes(array_merge($instance->getAttributes(), $foreign));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, shouldn't you be able to just call $instance->fill(array_merge($attributes, $foreign));?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The foreign key will rarely be fillable.

@bencorlett
Copy link
Contributor

Just left you a comment... Also, you will need to make get unit tests passing to get this merged :)

@vlakarados
Copy link
Author

@bencorlett I'm currently working on making tests work, I'm not so experienced at them so it may take a while, but will get them working. The point in why didn't I make the fill() call directly is the same why it wasn't implemented before - in most cases you don't want your foreign keys be fillable, if they're not in the $fillable array they won't be set and filtered out by fill(), this way we'll have all the user input filtered and filled and only after that the setRawAttributes() will update the foreign keys.

@vlakarados
Copy link
Author

Looks like it passes tests now, I want to mention the tests were made by @anlutro. Big thanks to him.

@cheelahim
Copy link

Another point is that $instance->fill($attributes); calls $this->setAttribute($key, $value) which in its turn triggers attribute mutators accordingly. In other words without @vlakarados fix mutators will be ignored while related model creating. I found current situation counterintuitive.

@danharper
Copy link
Contributor

I just wanted to give a quick +1 to this issue as I've just been chasing code around the framework trying to work out why my set mutators weren't firing. It was due to the relation's create method using setRawAttributes instead of fill. It seems very counter-intuitive.

This PR should fix these issues, unless there was another reason that it's always been like this?

@taylorotwell
Copy link
Member

Fixed this a tad differently... will be on 4.2.

@danharper
Copy link
Contributor

Awesome, cheers!

@taylorotwell
Copy link
Member

I would put it on 4.1 but if people are already working around it I don't want to break their work-arounds on a point release. So 4.2.

@vlakarados
Copy link
Author

Thank you! Really great!

@reneweteling
Copy link

@taylorotwell great work btw, but what workaround should we use in the meantime?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants