belongs_to will now trigger a validation error by default if the association is not present.
We can turn this off on a per-association basis with optional: true.
https://github.com/rails/rails/pull/18937
We will need a qualifier for this.
Okay -- do you plan on using optional: true? We tend to add qualifiers on an as-needed basis.
Yes. I'm developing a app where a Amiibo may or may not to belongs to Series. ex.: Sonic amiibo belongs to Smash Bros. Series, but Wolf Link amiibo belongs to none.
Cool. I'm not sure when I'll be able to get to this, as I am working on resolving some regressions with the 3.0 release right now, but I would happily take a PR, otherwise I'll get to it at some point down the line. I'll leave this open in the meantime since it's related to Rails 5.
I have a use-case for this as well.
I also have a use case for this. A food database where most of the foods are not created by users, but users can create foods and 'own' the foods that they create. Workaround: the admin user profile will own foods by default. Please correct me if there's a better workaround or existing solution.
Edit: It seems food does not have to belong_to anything, per this SO post. http://stackoverflow.com/questions/16699877/rails-optional-belongs-to Perhaps I have misunderstood the issue.
You can use belongs_to :user, optional: true for specific case or just put on application.rb config.active_record.belongs_to_required_by_default = false to config all application.
But shoulda-matcher doesn't have a matcher for this
@stephanngamedev I did neither of those things and it seems like I can create foods with user_id: nil no problem--am I missing something? My migration:
class AddUserToFoods < ActiveRecord::Migration
def change
add_reference :foods, :user, index: true, foreign_key: true
end
end
Are you using Rails 5?
I am using Rails 4. Sorry, I see now this thread is labeled Rails 5. Would your recommendations be necessary in Rails 5?
Yes. My recomendations is to make rails 5 belongs_to behavior like rails 4 belongs_to
@leoebrown Rails 5 changed the behavior of belongs_to so that it implicitly adds a presence validation for the association; optional: true disables that behavior. But in Rails 4 you don't really have to worry about this. If I remember correctly, if you leave your *_id column blank then your association will return nil (this works for both Rails 4 and 5). So you can use the belongs_to matcher in shoulda-matchers just fine without having to specify any additional qualifiers.
Hi! there is some progress on this?
I used to have validate association, presence: true back in Rails 4 to check that the referenced model exists and it was verified by a validate_presence_of. Now, in Rails 5, this is the default behaviour but if I remove the validation in the model to dry it up, the spec now fails because the errors messages diffier ("must exist" vs "can't be blank").
According to the new Rails behaviour, do you think that shoulda-matchers should test this by assigning nil and checking if and error was added? And if a qualifier was passed, the inverse check..
@vizcay for what it's worth, you can get the spec to pass by adding with_message(:required) like so:
is_expected.to validate_presence_of(association).with_message(:required)
Given a Rails 5 model with the association,
belongs_to :featured_plant, class_name: 'Plant', optional: true
I should be able to test the association with:
it { is_expected.to belong_to(:featured_plant).class_name('Plant').optional(true) }
to verify that the presence of an associated model is not required.
@ybakos, I tested it doesn't work on v3.1.1.
We are only testing for validation of the presence of the association ID, what if the given ID is invalid. And app behaviour is not to validate the existence of such association?
@mcmire @stephanngamedev Isn't that issue resolved by now?
Doesn't seem to work in version 3.1.2 for I am getting:
undefined method optional' for #<Shoulda::Matchers::ActiveRecord::AssociationMatcher
when I'm doing it { is_expected.to belong_to(:user).optional(true) }
Not sure why this issue wasn't closed automatically, but yes, this is resolved by #1058. It'll be available in the next version, or you're feeling adventurous, you can point to the master branch.
@mcmire When will this version be released?
The new code was merged 19th Oct 2017 but is still not present in the latest version!
Any news on this? Thanks :)
Failure/Error: it{is_expected.to belong_to(:position).optional true}
NoMethodError:
undefined method `optional' for #<Shoulda::Matchers::ActiveRecord::AssociationMatcher:0x00000000024649c8>
Did you mean? options
@namtx @Akhilesh05 @lucascaton We have a pre-release version out now! Try v4.0.0.rc1 to get optional.
In v4.0.0+, the usage is:
it { should belong_to(:sender).optional }
without the bool argument.
Most helpful comment
In v4.0.0+, the usage is:
without the bool argument.