I have two related models - let's say Activity
and Step
. Activity has_many :steps
and Step belongs_to :activity
which means the table for steps
has an activity_id
column.
This is in Hobo 1.3, so Rails 3.0.
What I want is to ensure that after Step
creation it is not possible to move a step to another Activity
. We don't want the activity_id
field to change.
I've removed the field from edit forms, but I'm looking for a stronger constraint. Essentially I want to validate on update
(not on create
) that the column isn't being touched. Hobo's documentation doesn't suggest anything of the sort inside Hobo, so I'm looking at Rails validations, but so far I haven't found the "only do this on update" constraint that I remember, nor a validation that something isn't changing.
You can declare an attribute as read_only with attr_readonly :your_field_name
. But this won't create an error if you try to write this attribute, it will fail silently. (This attribute will be ignored for all SQL-Updates)
Another option might be, to write a validation for this case, might look like this:
class Step < ActiveRecord::Base validate :activity_id_not_changed private def activity_id_not_changed if activity_id_changed? && self.persisted? errors.add(:activity_id, "Change of activity_id not allowed!") end end end
persisted?
returns true, if this is not a new record and it is not destroyed.
Links:
http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html#method-i-readonly_attributes
http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-persisted-3F
With validates inclusion:
validates :activity_id, inclusion: { in: ->(i) { [i.activity_id_was] } }, on: :update
No need for additional method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With