我有2个模型通过连接表相互关联:
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
上面的路线是使用rails的成员方法创建的:
resources :readers
member do
get 'books'
end
end
评论控制器中的更新操作(评论#update)定义如下:
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评论(评论#update)看起来像这样: 读者评论:
<% 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 %>
以上内容适用于更新。但第二种形式没有。
我的目的是检查评论=&gt;如果有的话 - 显示一个表格,以便读者可以更新评论;如果没有,则显示表单,以便读者可以创建评论。我在评论控制器中有一个私有方法,它检查以确保读者在执行任何操作之前都有一本书(我猜想是一个before_action方法)。
第一种形式运作良好(更新形式)但第二种形式不适用 - 表格根本不显示。我尝试了各种各样的东西来显示表格,但没有运气。你能否请我确定解决这个问题的最佳方法?
非常感谢!
答案 0 :(得分: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| %>
您当前正在将名为book
的本地变量传递给form_for
构建器。虽然这可能是正确的(我找不到您对创建book
的参考),但我发现最好在嵌套表单中放置一个符号(以显示Rails需要使用哪些数据)
答案 1 :(得分:0)
您可以尝试使用else
代替elsif !current_reader.reviews.include?(review)
吗?
此外,它是elsif
而不是elseif
。问题不应该因为这个问题 - 如果是这种情况,页面就不会首先加载。
答案 2 :(得分:0)
<强>更新强> 我通过更新表单修复了我的第一个错误: 读者评论:
<% 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 %>
显示表单(发布和更新)。 但是当我尝试发布新评论时出现此错误:
(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