Forum: Ruby on Rails Validation of other model fields

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ba86dfb8d0feeffb597c31aeb3b0ca3b?d=identicon&s=25 Daniello (Guest)
on 2007-05-01 20:18
(Received via mailing list)
I've got in my Form not only fileds from my model but also fields from
ither models. How can I validate them like other fields.

Example names od input tag fields

<p><label for="model1_name1">Name1</label>
<%= text_field 'model1', 'name1' , :size => 40 %></p>

<p><label for="model1_name2">Name2</label>
<%= text_field 'model1', 'name2' , :size => 40 %></p>

and from different model:

<p><label for="model2_name3">Name3</label>
<%= text_field 'model2', 'name3' , :size => 40 %></p>

How can I validate presence_of field name3 from model2 model??
72ea925c0ca3d19fdd2f12fa76681624?d=identicon&s=25 Stephan Wehner (stephanwehner)
on 2007-05-01 21:33
Daniello wrote:
> I've got in my Form not only fileds from my model but also fields from
> ither models. How can I validate them like other fields.
>
> Example names od input tag fields
>
> <p><label for="model1_name1">Name1</label>
> <%= text_field 'model1', 'name1' , :size => 40 %></p>
>
> <p><label for="model1_name2">Name2</label>
> <%= text_field 'model1', 'name2' , :size => 40 %></p>
>
> and from different model:
>
> <p><label for="model2_name3">Name3</label>
> <%= text_field 'model2', 'name3' , :size => 40 %></p>
>
> How can I validate presence_of field name3 from model2 model??

I'm not sure I understand your question.

Would your controller not say something like

  model1.update_attributes(params["model1"])
  model2.update_attributes(params["model2"])

Then if you call

  model1.save

it will not save if validation of model1 fails.

Likewise, model2.save will not save if model2 validation fails.

To save only if both validations pass you could call in your controller:

  model1_valid = model1.valid?
  model2_valid = model2.valid?

  if (model1_valid && model2_valid)
    model1.save_with_validation(false) # already validated
    model2.save_with_validation(false) # already validated
  else
    # How do you handle failed validations?
  end


But if your logic is that for this particular form, model2 should only
be saved if user has entered a value for a certain field of model1, then
you can perform that test in the controller:

  if params[:model1][:certain_field].blank?
    # handle error
  end

Stephan
8310c5a7c769345114597bcdef111488?d=identicon&s=25 Ben Munat (Guest)
on 2007-05-01 21:53
(Received via mailing list)
The update_attributes method saves as well as updating the attribute.

b
B09a3f6cdc4797532647d2d264b5df49?d=identicon&s=25 Jodi Showers (jshow)
on 2007-05-01 22:03
(Received via mailing list)
On 1-May-07, at 3:51 PM, Ben Munat wrote:

>>>
>>> <p><label for="model2_name3">Name3</label>
>>
>>
>>
>> Stephan
Daniello, hopefully the following will help move you forward. It will
leave you with an @errors for both models in your view that you can
iterate over

When managing validations for multiple models in one action I
typically use something like the following:

     @model1 = Model1.new(params[:model1])
     @model2 = Model2.new(params[:model2])

     respond_to do |format|
       if @ model1.valid? && @ model2.valid?
         #TODO: transaction here would help out
         @ model1.save(false)
         @ model1.save(false)
         flash[:notice] = 'Model1 and Model2 were successfully created.'
         format.html { render :partial => "my_partial" }
       else
         flash[:notice] = 'There were errors validating model1, model2'
         #merge_errors (below), merges the errors of 2 models into
one errors list
         format.html { @errors = merge_errors(@model1, @model2);
render :partial => "/error_messages", :errors => @errors, :status =>
500 }
       end
     end

   #merges errors from 2 instances into 1 error object
   def merge_errors(model1, model2)
     if model1.errors.size > 0 && model2.errors.size > 0
       model1.errors.instance_eval { @errors.merge
model2.errors.instance_values['errors'] }
     elsif model1.errors.size > 0
       model1.errors
     elsif model2.errors.size > 0
       model2.errors
     else
       model1.errors
     end
   end

Cheers,
Jodi
General Partner
The nNovation Group inc.
www.nnovation.ca/blog
231cf7eaedd8e00cb0176dd1a4e85ce2?d=identicon&s=25 Bas van Westing (Guest)
on 2007-05-02 16:56
(Received via mailing list)
Daniello,

If there is a model association between the two models you can use the
following (copy/pasted from api.rubyonrails.org):

validates_associated(*attr_names)

Validates whether the associated object or objects are all valid
themselves. Works with any kind of association.

  class Book < ActiveRecord::Base
    has_many :pages
    belongs_to :library

    validates_associated :pages, :library
  end

Warning: If, after the above definition, you then wrote:

  class Page < ActiveRecord::Base
    belongs_to :book

    validates_associated :book
  end

...this would specify a circular dependency and cause infinite
recursion.

NOTE: This validation will not fail if the association hasn't been
assigned. If you want to ensure that the association is both present
and guaranteed to be valid, you also need to use
validates_presence_of.

Configuration options:

    * on Specifies when this validation is active (default is :save,
other options :create, :update)
    * if - Specifies a method, proc or string to call to determine if
the validation should

occur (e.g. :if => :allow_validation, or :if => Proc.new { |user|
user.signup_step > 2 }). The method, proc or string should return or
evaluate to a true or false value.

Regards,
Bas van Westing
B09a3f6cdc4797532647d2d264b5df49?d=identicon&s=25 Jodi Showers (jshow)
on 2007-05-02 17:11
(Received via mailing list)
On 2-May-07, at 10:55 AM, Bas van Westing wrote:

>
>     belongs_to :book
> validates_presence_of.
> evaluate to a true or false value.
>
> Regards,
> Bas van Westing
>
>

now how did I miss that ?!

This is clearly a better route to go - for you and me, Daniello.

thanx Bas

Jodi
This topic is locked and can not be replied to.