Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First of all, I want to be sure that you mean <code>blank?</code> rather than <code>present?</code>. Typically, I see this:</p> <pre><code>validate :address, :presence_of =&gt; true, :if =&gt; 'organisation.present?' </code></pre> <p>Meaning, you only want to validate address if organisation is also present.</p> <p>Regarding, <code>:accepts_nested_attributes_for</code>, are you using this feature by passing in nested form attributes, or some such thing? I just want to make sure you absolutely need to use this functionality. If you are not actually dealing with nested form attributes, you can implement cascading validation using:</p> <pre><code>validates_associated :address </code></pre> <p>If you do need to use <code>:accepts_nested_attributes</code>, be sure to check out the <code>:reject_if</code> parameter. Basically, you can reject adding an attribute (and it's descendants) altogether if certain conditions apply:</p> <pre><code>accepts_nested_attributes_for :address, :allow_destroy =&gt; true, :reject_if =&gt; :no_organisation def no_organisation(attributes) attributes[:organisation_id].blank? end </code></pre> <p>Now, if none of the above apply, let's take a look at your syntax:</p> <p>It should work, <code>:if/:unless</code> take <a href="http://guides.rubyonrails.org/active_record_validations_callbacks.html#conditional-validation" rel="nofollow noreferrer">symbols, strings and procs</a>. You don't need to point to the foreign_key, but can simplify by pointing to:</p> <pre><code>:if =&gt; "organisation.blank?" </code></pre> <p>You have other validations in the Address model, correct? Is Address being validated when you don't want it to? Or is Address not being validated? I can help you test it out in the console if you can give me some additional details.</p> <hr> <ol> <li>To make things easier for myself re: mass-assignment, I changed the rails config: <code>config.active_record.whitelist_attributes = false</code></li> <li>I created <a href="https://gist.github.com/3853702" rel="nofollow noreferrer">a gist for you to follow along</a></li> <li><p>I have a sample project as well. Let me know if you are interested.</p> <p>Basic points:</p></li> <li><p>Added the following to Person to ensure that either Org or Address are valid:</p> <p><code>validates_presence_of :organisation, :unless =&gt; "address.present?"</code> <code>validates_associated :address, :unless =&gt; "organisation.present?"</code></p></li> <li><p>Added validation to Address to trigger errors when Org is not present: <code>validates_presence_of :line1, :line2, :city, :zip</code></p> <p>I was able to produce the requirements you are seeking. Please look <a href="https://gist.github.com/3853702" rel="nofollow noreferrer">at the gist I created</a> where I have a full console test plan.</p></li> </ol> <hr> <p>I added <a href="https://gist.github.com/3853702#file_controller.rb" rel="nofollow noreferrer">a controller file to the previous gist</a>.</p> <p>Overview:</p> <ol> <li>All you should need to create the person is: <code>@person = current_user.people.build(params[:person])</code></li> <li>:organisation_id will always be found off of the :person param node, like so: <code>params[:person][:organisation_id]</code> So you're if will never be true.</li> </ol> <hr> <p>I updated the gist with the necessary changes to <a href="https://gist.github.com/3853702#file_person_controller.rb" rel="nofollow noreferrer">the controller</a>, <a href="https://gist.github.com/3853702#file_models.rb" rel="nofollow noreferrer">the model</a> and <a href="https://gist.github.com/3853702#file__fields.html.erb" rel="nofollow noreferrer">the form</a>.</p> <p>Overview:</p> <ol> <li>You need to cleanup your controller. You are using <code>accepts_nested_attribute</code>, so in the :create, you only care about <code>params[:person]</code>. Additionally, in the <code>render :new</code>, you need to setup any instance variables that the partial will use. This does <strong>NOT</strong> go back through the <code>:new</code> action. The <code>:new</code> and <code>:edit</code> actions also need to be simplified.</li> <li>Your Person model needs to use the <code>:reject_if</code> argument because the Address fields are coming back to the :create action as <code>:address_attributes =&gt; {:line1 =&gt; '', :line2 =&gt; '', etc}</code>. you only want to create the association if any have values. Then your <code>validates_presence_of</code> for <code>:organisation</code> will work just fine.</li> <li><p>Your form needs to pass the organisation id to the controller, rather than the organisation names</p> <p>It's all in <a href="https://gist.github.com/3853702" rel="nofollow noreferrer">the gist</a></p></li> </ol> <hr> <p>Should be <a href="https://gist.github.com/3879505" rel="nofollow noreferrer">the final gist</a>.</p> <p>Overview:</p> <ol> <li><p>Add the following to your edit action right after building the @person:</p> <p>@person.build_address if @person.address.nil? This ensure that you have the address inputs, even if the @person.address does not exist. It doesn't exist, because of the :reject_if condition on accepts_nested_attributes</p></li> <li><p>I DRYed up the :reject_if as follows. It's a little hacky, but has some utility: </p> <pre><code>accepts_nested_attributes_for :address, :allow_destroy =&gt; true, :reject_if =&gt; :attributes_blank? def attributes_blank?(attrs) attrs.except('id').values.all?(&amp;:blank?) end </code></pre> <p>a. <code>attrs</code> -> the result of params[:person][:address]<br> b. <code>.except('id')</code> -> return all key-values except for 'id'<br> c. <code>.values</code> -> return all values from a hash as an array<br> d. <code>.all?</code> -> do all elements in the array satisfy the following check<br> e. <code>&amp;:blank</code> -> ruby shorthand for a block, like this: <code>all?{ |v| v.blank? }</code></p></li> </ol>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload