Rails 4 _form部分创建新记录,但不会编辑当前记录
我已经构建了一个具有业务的简单应用程序,并且这些业务有很多评论。我正在使用部分_form来创建/更新评论。创建操作可以正常工作,但更新操作会创建一个新的审阅,而不是像审查时那样更新审阅。下面是相关的代码(不相关的代码简洁,删除):Rails 4 _form部分创建新记录,但不会编辑当前记录
从routes.rb
代码:
resources :businesses do
resources :reviews
end
从models/business.rb
代码:
class Business < ActiveRecord::Base
has_many :reviews, dependent: :destroy
validates_associated :reviews
end
从models/review.rb
代码:
class Review < ActiveRecord::Base
belongs_to :business
belongs_to :user
end
代码从controllers/reviews_controller.rb
:
class ReviewsController < ApplicationController
load_and_authorize_resource
before_filter :load_business
def new
end
def index
end
def create
@review = @business.reviews.create(review_params)
@review.user_id = current_user.id
@review.reviewer = current_user.first_name + ' ' + current_user.last_name
if @review.save
redirect_to business_path(@business)
flash[:notice] = 'Review posted!'
else
redirect_to business_path(@business)
flash[:danger] = 'Your review has an error. Please double check!'
end
end
def edit
@review = @business.reviews.find(params[:id])
end
def update
@review = @business.reviews.find(params[:id])
if @review.update(params[review_params])
redirect_to businesses_path(@business)
flash[:notice] = 'Review updated!'
else
render :action => 'edit'
end
end
def destroy
@review = @business.reviews.find(params[:id])
@review.destroy
redirect_to business_path(@business)
flash[:notice] = "Review deleted."
end
private
def load_business
@business = Business.find(params[:business_id])
end
def review_params
params.require(:review).permit(:review, :rating)
end
end
代码`评论/ _form.html.erb:
<%= simple_form_for([@business, @business.reviews.build]) do |f| %>
<%= f.error_notification %>
<p>
<%= f.input :review %>
</p>
<p>
<%= f.input :rating, collection: 1..10 %>
</p>
<p>
<%= f.submit :class => 'btn btn-primary' %>
</p>
<% end %>
的评语是在商业#放映视图作为部分呈现。代码`评论/ _review.html.erb:
<% if !review.user_id.nil? %>
<div class="well">
<p>
<strong>Reviewer:</strong>
<%= review.reviewer %>
</p>
<p>
<strong>Review:</strong>
<%= review.review %>
</p>
<p>
<strong>Rating:</strong>
<%= review.rating %>
</p>
<span class = "timestamp">
posted <%= time_ago_in_words(review.created_at) %> ago.
</span>
<% if can? :update, review %>
<span class = "timestamp">
<%= link_to "Edit", [:edit, review.business, review], class: 'btn btn-small' %>|
<%= link_to "Delete", [review.business, review], method: :delete,
data: { confirm: 'Are you sure?' } %>
</span>
<% end %>
</div>
<% end %>
代码reviews/edit.html.erb
:
<h1>Edit Review</h1>
<%= render 'form', review: @review %>
<button type="button" class="btn btn-default"><%= link_to 'Back', businesses_path %></button>
奇怪的是,当我点击_review.html.erb
“编辑” 链接,这是生成的URL似乎是正确的,例如我得到http://localhost:3000/businesses/10/reviews/82/edit
。然而,_form.html.erb是空的,我期望它会被当前的数据填充#82。此外,当我点击“创建评论”按钮时,它会创建一个新的评论,并且不会编辑评论#82。
这里后,我的服务器日志点击现有的评论“编辑”:
Started GET "/businesses/3/reviews/81/edit" for 127.0.0.1 at 2014-08-28 19:18:58 -0500
Processing by ReviewsController#edit as HTML
Parameters: {"business_id"=>"3", "id"=>"81"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 8 ORDER BY "users"."id" ASC LIMIT 1
Review Load (6.9ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."id" = $1 LIMIT 1 [["id", 81]]
Business Load (0.5ms) SELECT "businesses".* FROM "businesses" WHERE "businesses"."id" = $1 LIMIT 1 [["id", 3]]
Review Load (27.4ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."business_id" = $1 AND "reviews"."id" = $2 LIMIT 1 [["business_id", 3], ["id", 81]]
Rendered reviews/_form.html.erb (107.0ms)
Rendered reviews/edit.html.erb within layouts/application (143.4ms)
Completed 200 OK in 967ms (Views: 669.2ms | ActiveRecord: 35.6ms)
Started POST "/businesses/3/reviews" for 127.0.0.1 at 2014-08-28 19:19:23 -0500
Processing by ReviewsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"<redacted>", "review"=>{"review"=>"Edit review #81.", "rating"=>"1"}, "commit"=>"Create Review", "business_id"=>"3"}
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 8 ORDER BY "users"."id" ASC LIMIT 1
Business Load (0.6ms) SELECT "businesses".* FROM "businesses" WHERE "businesses"."id" = $1 LIMIT 1 [["id", 3]]
(28.9ms) BEGIN
SQL (132.9ms) INSERT INTO "reviews" ("business_id", "created_at", "rating", "review", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["business_id", 3], ["created_at", "2014-08-29 00:19:23.470750"], ["rating", 1], ["review", "Edit review #81."], ["updated_at", "2014-08-29 00:19:23.470750"]]
(39.7ms) COMMIT
(0.3ms) BEGIN
SQL (0.9ms) UPDATE "reviews" SET "reviewer" = $1, "updated_at" = $2, "user_id" = $3 WHERE "reviews"."id" = 83 [["reviewer", "<redacted>"], ["updated_at", "2014-08-29 00:19:23.692880"], ["user_id", 8]]
(17.5ms) COMMIT
Redirected to http://localhost:3000/businesses/3
Completed 302 Found in 553ms (ActiveRecord: 221.6ms)
Started GET "/businesses/3" for 127.0.0.1 at 2014-08-28 19:19:23 -0500
Processing by BusinessesController#show as HTML
Parameters: {"id"=>"3"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 8 ORDER BY "users"."id" ASC LIMIT 1
Business Load (0.5ms) SELECT "businesses".* FROM "businesses" WHERE "businesses"."id" = $1 LIMIT 1 [["id", 3]]
(0.5ms) SELECT AVG("reviews"."rating") AS avg_id FROM "reviews" WHERE "reviews"."business_id" = $1 [["business_id", 3]]
Rendered reviews/_form.html.erb (5.7ms)
Review Load (0.6ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."business_id" = $1 ORDER BY "reviews"."id" DESC [["business_id", 3]]
Rendered reviews/_review.html.erb (58.1ms)
Rendered businesses/show.html.erb within layouts/application (173.5ms)
Rendered users/_avatar.html.haml (13.1ms)
Rendered layouts/_navigation.html.haml (30.9ms)
Rendered layouts/_messages.html.haml (1.5ms)
Rendered layouts/_footer.html.haml (16.5ms)
Rendered layouts/_analytics.html.haml (0.6ms)
Rendered layouts/_javascripts.html.haml (0.5ms)
Completed 200 OK in 421ms (Views: 391.5ms | ActiveRecord: 2.3ms)
很明显的是,在服务器日志中的第二个动作为“已启动POST ......”,这是不正确的。而我在这,我不妨从rake routes
提供相关路线:
business_reviews GET /businesses/:business_id/reviews(.:format) reviews#index
POST /businesses/:business_id/reviews(.:format) reviews#create
new_business_review GET /businesses/:business_id/reviews/new(.:format) reviews#new
edit_business_review GET /businesses/:business_id/reviews/:id/edit(.:format) reviews#edit
business_review GET /businesses/:business_id/reviews/:id(.:format) reviews#show
PATCH /businesses/:business_id/reviews/:id(.:format) reviews#update
PUT /businesses/:business_id/reviews/:id(.:format) reviews#update
DELETE /businesses/:business_id/reviews/:id(.:format) reviews#destroy
我已经尝试实现每一个答案,我能找到这里,但无济于事。我发现的最接近我的确切问题是这一个,但它也没有帮助:Rails: Use same partial for creating and editing nested items
非常感谢。
根据你在控制台中的输出,你在更新stmt之前有一个sql插入stmt。您的代码在表单中导致它。即使在编辑时,@business.reviews.build
也会创建新的审阅对象。
更新您的form_for到:
<%= simple_form_for([@business, @review]) do |f| %>
而不是@business.reviews.build
。您应该在控制器而不是视图中创建对象。
因此,您可能还需要在新操作中重新检查对象。
def new
@review = @business.reviews.build
end
我为你简化代码,可以使事情变得更容易一些建议。
使用评论ID来查找评论,而不是通过业务。
如编辑和修改代码,你可以:
def edit
@review = Reviews.find(params[:id])
end
def update
@review = Reviews.find(params[:id])
...
end
当我做出前2次更改并单击来自business#index的业务时,我收到此错误:'NoMethodError at/businesses/3:未定义方法'model_name'for NilClass:Class'。我改变了您的更改,以便我可以选择一个业务,并在业务#show上重新进行一次更改。我可以点击评论上的“编辑”,它会将我带到正确填写表格的编辑页面。单击表单上的“更新”会引发以下错误:'ArgumentError at/businesses/3/reviews/84:分配属性时,必须将散列作为参数传递。' – 2014-08-29 15:47:56
1.我错过了这个部分,在没有评论的时候,你应该在商业#节目上做@ @ business.reviews.build'。 2.更新的'ArgumentError'可能由'@ review.update(params [review_params])'的代码引起。我认为应该更改为'@ review.update(review_params)' – 2014-08-29 16:25:04
该修复允许编辑评论,假设我使用了正确版本的表单。如果我使用'[@business,@ business.reviews.build]'版本,点击'编辑'会创建一个新的评论。如果我将其更改为'[@business,@review]'版本,然后点击'编辑',则表单将被预填充并正确更新。但是,如果我使用这个版本,我甚至无法进入商业#show。我得到了前面提到的第一个错误。这就是为什么一旦我登陆商业#展会就要改变它。这就像需要表单的两个版本。我错过了什么?这不就是为什么我们首先使用偏分量吗? – 2014-08-29 17:14:19
尝试增加':id'到''review_params' params.require(:综述).permit(:身份证,:回顾,:等级) ' – Pavan 2014-08-29 05:42:53
我使用review_params的唯一时间是在CREATE期间。当ID被添加到数据库时,不会被分配吗?它真的需要被允许吗? – 2014-08-29 15:02:08