2014-03-04 101 views
1

我有通過一個連接表相互關聯的2種型號:的form_for助手

class Book < ActiveRecord::Base 
    has_many :reviews 
end 

class Reader < ActiveRecord::Base 
    has_many :reviews 
end 

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

現在,我可以在路由更新的評論(我在控制檯中手動創建):

readers/:id/books 

上述路線是使用軌道構件的方法創建:

resources :readers 
    member do 
    get 'books' 
    end 
end 

在評論對照的更新動作奧勒(評論#更新)的定義,像這樣:

def update 
    @reader = current_reader 
    @review = Review.find_by_reader_id(@reader.id) 
    @book = Book.find(params[:review][:book] 
    if @reader.books.include?(@book) 
    @review.update_attributes(review_params) 
    redirect_to (@reader) 
    else 
    flash[:error] = 'You can only edit reviews that belong to you' 
    end 
end 

我的form_for評論(評論#更新)看起來是這樣的: 讀者評論:

<% book.reviews.each do |review| %> 
    <% if current_reader == (review.reader) %> 
    <%= review.content %> written by <%= review.reader.name %> 
    <% if current_reader.reviews.include?(review) %> 
     <%= form_for ([book, review]) do |f| %> 
     <div class="field"> 
     <%= f.hidden_field :book, :value => book.id %> 
     <%= f.text_area :content, placeholder: "compose new review" %> 
     </div> 
     <%= f.submit "Update", class: "btn btn-large btn-primary" %> 
    <% else %> 
     <%= form_for ([book, review]) do |f| %> 
     <div class="field"> 
      <%= f.hidden_field :book, :value => book.id %> 
      <%= f.text_area :content, placeholder: "compose new review" %> 
     </div> 
     <%= f.submit "Post", class: "btn btn-large btn-primary" %> 
     <% end %> 
    <% end %> 
    <% end %> 
<% end %> 

上述工程進行更新。但是第二種形式沒有。

我的意圖是檢查評論=>如果有的話 - 顯示錶格以便讀者可以更新評論;如果沒有人會顯示一個表格,以便讀者可以創建一個評論。我在評論控制器中有一個私有方法,在進行任何操作之前檢查以確保讀者擁有一本書(我猜想是before_action方法)。

第一種形式很好(更新形式),但第二種形式沒有 - 形式根本不顯示。我嘗試了各種各樣的東西來獲得表格來顯示,但沒有運氣。您能否請我確定解決此問題的最佳方法?

非常感謝!

回答

0

可能有幾個問題:

ELSIF

可能的原因您的其它形式將不會顯示將是您的elsif邏輯將是不正確的

我看看在.include? Ruby函數中,它似乎只適用於數組。爲什麼不嘗試使用.exists?呢?

<% elseif !current_reader.reviews.exists?(review) %> 

您可能必須使用review.id或類似名稱才能獲得正確的響應。如果沒有,那你爲什麼不使用<% else %>


的form_for

第二個問題可能是你的第二個form_for

<%= form_for [:book, review] do |f| %> 

您目前正在通過所謂的bookform_for建設者的局部變量。雖然這可能是正確的(我找不到創建book的參考),但我發現最好在嵌套表單中放置一個符號(以顯示Rails需要使用哪種數據)

+0

您嘗試過嗎? –

+1

對不起!意外命中輸入:( 我確實嘗試了你的兩條建議: 將**。include **改爲**。exists **,並將** elsif **改爲** else **。表單顯示在頁面上的是更新表單我仍然無法顯示創建新評論的表單 我現在正在上學途中,但我會盡快更新我的問題(提供更多信息)因爲我進來了。謝謝你的幫助! – Uzzar

+0

沒問題!等不及要讀你的更新 –

0

您可以嘗試用else代替elsif !current_reader.reviews.include?(review)

此外,它是elsif而不是elseif。這個問題不應該因爲這個原因 - 如果是這種情況,頁面將不會首先加載。

0

UPDATE 我通過更新我的形式固定我的第一個錯誤: 讀者評論:

<% book.reviews.where(reader_id: current_reader.id).each do |review| %> 
    <li> 
    <span><%= review.content %> writen by <%= review.reader.name %> </span 
    <%= form_for ([book, review]) do |f| %> 
     <div class="field"> 
     <%= f.hidden_field :book, :value => book.id %> 
     <%= f.text_area :content, placeholder: "compose new review" %> 
     </div> 
     <%= f.submit "Update", class: "btn btn-large btn-primary" %> 
    <% end %> 
    </li> 
    <% if book.reviews.where(reader_id: current_reader.id).size == 0 %> 
     <%= form_for ([book, book.reviews.build]) do |f| %> 
     <div class="field"> 
      <%= f.hidden_field :book, :value => book.id %> 
      <%= f.text_area :content, placeholder: "compose new review" %> 
     </div> 
     <%= f.submit "Post", class: "btn btn-large btn-primary" %> 
    <% end %> 
    <% end %> 
<% end %> 

這顯示形式(POST和更新)。 我得到這個錯誤,當我試圖發表新的評論:

(rdb:35) @review 
#<Review id: nil, reader_id: 101, content: "Trial", created_at: nil, updated_at: nil, book_id: nil> 
(rdb:35) review_params 
Unpermitted parameters: book 
{"content"=>"Trial"} 
(rdb:35) 

所以我改變了我的審查創建行動,以確保book_id不nill:

def create 
    @reader = current_reader 
    # @book = Book.find(params[:book_id]) 
    @book = Book.find(params[:review][:book]) 
    if @reader.reviews.where(book_id: @book.id).exists? 
    flash[:error] = "You already reviewed this book" 
    else 
    @review = current_reader.reviews.create(:book_id => params[:book_id.to_i, :content => review_params[:content]) 
    debugger 
    if @review.save 
     flash[:success] = "Review created" 
     redirect_to reader_path(@reader) 
    else 
     flash[:error] = "You can only review books that are in your library" 
     redirect_to reader_path(@reader) 
    end 
    end 
end 

也發生了變化如何我定義了review_params:

def review_params 
    params.require(:review).permit(:content, :book_id) 
end 

所有這些變化都給出了預期的結果。我的代碼並不幹,但在這一點上對我來說最重要的事情就是讓事情發揮作用。這裏是希望我不要再打破它。感謝您的幫助@RichPeck