Search code examples
ruby-on-railsform-forcontroller-actions

Rails4: creating and editing an object, through its association to another object, to a form_for helper


I have 2 models that are associated with each other via a join table:

class Book < ActiveRecord::Base
  has_many :reviews
  has_many :readers, through: :libraries 
end

class Reader < ActiveRecord::Base
  has_many :reviews
  has_many :books, through: :reviews 
end

class Reviews < ActiveRecord::Base
  belongs_to :reader
  belongs_to :book
end

Review has the following columns:

  • content
  • reader_id
  • book_id

The show action in books controller (book#show) is defined like so:

def show
  @book = book.find[:id]
end

The main idea is this: A Reader has to have read a book to review it (no book? reader can't write review for book)

In book's view for show (show.html.erb) I can access both review and reader objects that belong to a book like so:

Book Reviews

<% @book.reviews.each do |review| %>
<%= review.content %> written by <%= review.reader.name %>

Everyone can see a Book's profile but only those that are signed in AND have bought the book can review the book. I have to a form_for helper for @review object and it is in my shared folder (under views). My form_for helper my @review object looks like this:

<%= form_for(review) do |f| %>
  <div class="field">
    <%= f.text_area :content, placeholder: "compose new review" %>
  </div>
  <%= f.submit "Update", class: "btn btn-large btn-primary" %>
<% end %>

My Problem is this: I want to readers to be able to edit their reviews of a book while on the books' profile page (book#show). I have an if/else statement that checks to see that only readers who are signed in and have bought the book can create/update a review. It looks something like this: Book Reviews

<% @book.reviews.each do |review| %>
 <%= review.content %> | written by <%= review.reader.name %>
   <% if signed_in? && current_reader?(review.reader) %>
     <div class="row">
       <aside class="span4">
         <section>
           <%= render 'shared/review_form', review: review %>
         </section>
       </aside>
      </div>
    <% else %>
       #Do something else
    <% end %>
<%end%>

I get an error this error:

undefined method `model_name' for #<Class:0x007fe568871c70>

I think this is because class in the error above is book and the model is @review? Can someone please help me figure out how I can pass the review object that I access via @book to to the form_for helper for @review?

Thank you very much!


Solution

  • You have a form_for @review but you aren't defining @review anywhere.

    I would alter this line:

    render 'shared/review_form'
    

    to pass the current review into the partial as a local variable:

    render 'shared/review_form', review: review
    

    And then you can change the review_form to be form_for review.