开发者

Rails validation context

I need help with my ActiveRecord model. I have context based validations (mis)using the build-in context options for validations:

validates :foo, :on => :bar, :presence => true

model = Model.new
model.foo = nil
model.valid? # => true
model.save # works as expected

model.valid?(:bar) # => false
model.save(:context => :bar) # fails and returns false

But using my model in a accepts_nested_attributes_for :model and calling parent.save fails (the validation gets called and returns false), any suggestions or solutions?


Still no answer? To explain more about my problem: I have a model called Form which has many Fields. Users should see validation errors on submit, but the form should be saved anyway (with and without errors). There are different types of Fields, each with global validations (to ensure database consistency) and its own specific user-defined validations (to validate user-entered data). So my Fields look开发者_运维知识库 someway like that:

 # Global validations, to ensure database consistency
 # If this validations fail, the record should not be saved!
 validates_associated :form, :on => :global
 ...

 # Specific user-defined validations
 # If this validations fail, the record should be saved but marked as invalid. (Which is done by a before_save filter btw.)
 def validate
   validations.each do |validation| # Array of `ActiveModel::Validations`, defined by the user and stored in a hash in the database
     validation.new(:on => :specific).validate(self)
   end
 end

In my controller:

 # def create
 # ...
 form.attributes = params[:form]
 form.save!(:global)
 form.save(:specific)

Is something similar possible in Rails using the built-in functionality? Btw this not my actual code, which is quite complicated. But I hope, you guys will get the idea.


Try conditional validations

class Customer 
  attr_accessor :managing 

  validates_presence_of :first_name
  validates_presence_of :last_name 

  with_options :unless => :managing do |o|
    o.validates_inclusion_of :city, :in=> ["San Diego","Rochester"]
    o.validates_length_of :biography, :minimum => 100 
  end
end

@customer.managing = true
@customer.attributes = params[:customer]
@customer.save


"Ability to specify multiple contexts when defining a validation" was introduced in Rails 4.1 - check validate method, :on options description


Only for Rails 5+:

You are looking for

with_options on: :custom_event do
  validates :foo, presence: true
  validates :baz, inclusion: { in: ['b', 'c'] }
end

To validate or save use

model = YourModel.new

# Either
model.valid?(:custom_event)

# Or
model.save(context: :custom_event)


Change has_nested_attributes_for :model to accepts_nested_attributes_for :models.

Hope this helps.

Good luck.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜