简体   繁体   中英

Prevent change of one field in Rails model

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.

I think you can do this too with the Hobo permissions system: http://hobocentral.net/manual/permissions

For example:

def update_permitted?
  acting_user.administrator && !activity_id_changed?
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM