Form_for 助手
Posted
技术标签:
【中文标题】Form_for 助手【英文标题】:Form_for helper 【发布时间】:2014-03-04 08:06:52 【问题描述】:我有 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
评论控制器中的更新操作(reviews#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 评论 (reviews#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 %>
以上适用于更新。但第二种形式没有。
我的意图是检查评论 => 如果有 - 显示一个表格,以便读者可以更新评论;如果没有,则显示一个表格,以便读者可以创建评论。我在评论控制器中有一个私有方法,可以在执行任一操作之前检查以确保读者有书(我猜是 before_action 方法)。
第一个表单(更新表单)运行良好,但第二个不行——表单根本不显示。我尝试了各种方法来显示表单,但没有运气。能否请我确定解决此问题的最佳方法?
非常感谢!
【问题讨论】:
【参考方案1】:可能有几个问题:
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 显示它需要使用哪些数据)
【讨论】:
抱歉!不小心按回车:(我确实尝试了你的两个建议:将 .include? 更改为 .exists? 并将 elsif 更改为 否则。不幸的是,页面上显示的唯一表单是更新表单。我仍然无法显示用于创建新评论的表单。我现在正在去学校的路上,但我会更新我的问题(提供更多信息)我一进去。谢谢你的帮助! 添加了我的答案!感谢您的帮助:)【参考方案2】:您可以尝试使用else
代替elsif !current_reader.reviews.include?(review)
吗?
另外,它是elsif
而不是elseif
。问题不应该是因为这个 - 如果是这种情况,页面一开始就不会加载。
【讨论】:
【参考方案3】:更新 我通过更新表单修复了我的第一个错误: 读者评论:
<% 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 不为零:
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
【讨论】:
以上是关于Form_for 助手的主要内容,如果未能解决你的问题,请参考以下文章