Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you declare an optional condition for an ActiveRecord belongs_to association?

Rails ActiveRecord provides an optional option for belongs_to. Consider the use case of allowing null for the foreign key and allowing the association to be null during object creation but requiring its presence during subsequent saves. For example, a new Member may have no initial Group, but any further updates of Member require a Group association.

Can the optional option value itself be conditional? For example,

class Member < ApplicationRecord
  belongs_to :group, optional: -> { new_record? }
end

behaves the same as optional: true, and we can infer that the optional option parsing only checks for a truthy value.

Is a custom validator the pragmatic way to meet this use case?

like image 919
ybakos Avatar asked Dec 30 '17 17:12

ybakos


People also ask

Is Belongs_to optional in Rails?

belongs_to associations are now automatically required: true So if the association is optional, that must be declared, or validation will fail without the presence of the associated model record.

What is optional true in Rails?

What is optional true in rails? If you set the :optional option to true, then the presence of the associated object won't be validated. By default, this option is set to false . otherwise it will be required associated object.29-Aug-2020.

What is the difference between Has_one and Belongs_to?

They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user . To determine who "has" the other object, look at where the foreign key is.

What does Belongs_to do in Rails?

belongs_to means that the foreign key is in the table for this class. So belongs_to can ONLY go in the class that holds the foreign key. has_one means that there is a foreign key in another table that references this class.


1 Answers

It looks like providing a lambda to the optional option won't work (although I haven't tried it). I looked at the source code and this is how optional is used.

required = !reflection.options[:optional]

If required, Rails just adds a presence validation like this:

model.validates_presence_of reflection.name, message: :required

I believe you could go the custom route with something like this:

class Member < ApplicationRecord
  belongs_to :group, optional: true
  validates :group, presence: true, on: :update
end
like image 140
Derek Hopper Avatar answered Nov 04 '22 16:11

Derek Hopper