Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can you validate the presence of a belongs to association with Rails?
    primarykey
    data
    text
    <p>Say I have a basic Rails app with a basic one-to-many relationship where each comment belongs to an article:</p> <pre><code>$ rails blog $ cd blog $ script/generate model article name:string $ script/generate model comment article:belongs_to body:text </code></pre> <p>Now I add in the code to create the associations, but I also want to be sure that when I create a comment, it always has an article:</p> <pre><code>class Article &lt; ActiveRecord::Base has_many :comments end class Comment &lt; ActiveRecord::Base belongs_to :article validates_presence_of :article_id end </code></pre> <p>So now let's say I'd like to create an article with a comment all at once:</p> <pre><code>$ rake db:migrate $ script/console </code></pre> <p>If you do this:</p> <pre><code>&gt;&gt; article = Article.new =&gt; #&lt;Article id: nil, name: nil, created_at: nil, updated_at: nil&gt; &gt;&gt; article.comments.build =&gt; #&lt;Comment id: nil, article_id: nil, body: nil, created_at: nil, updated_at: nil&gt; &gt;&gt; article.save! </code></pre> <p>You'll get this error:</p> <pre><code>ActiveRecord::RecordInvalid: Validation failed: Comments is invalid </code></pre> <p>Which makes sense, because the comment has no page_id yet. </p> <pre><code>&gt;&gt; article.comments.first.errors.on(:article_id) =&gt; "can't be blank" </code></pre> <p>So if I remove the <code>validates_presence_of :article_id</code> from <code>comment.rb</code>, then I could do the save, but that would also allow you to create comments without an article id. What's the typical way of handling this?</p> <p><strong>UPDATE</strong>: Based on Nicholas' suggestion, here's a implementation of save_with_comments that works but is ugly:</p> <pre><code>def save_with_comments save_with_comments! rescue false end def save_with_comments! transaction do comments = self.comments.dup self.comments = [] save! comments.each do |c| c.article = self c.save! end end true end </code></pre> <p>Not sure I want add something like this for every one-to-many association. Andy is probably correct in that is just best to avoid trying to do a cascading save and use the nested attributes solution. I'll leave this open for a while to see if anyone has any other suggestions. </p>
    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.
 

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