Pregunta

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.

¿Fue útil?

Solución

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

Otros consejos

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top