2014-08-29 93 views
0

我已經構建了一個具有業務的簡單應用程序,並且這些業務有很多評論。我正在使用部分_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

非常感謝。

+0

嘗試增加':id'到''review_params' params.require(:綜述).permit(:身份證,:回顧,:等級) ' – Pavan 2014-08-29 05:42:53

+0

我使用review_params的唯一時間是在CREATE期間。當ID被添加到數據庫時,不會被分配嗎?它真的需要被允許嗎? – 2014-08-29 15:02:08

回答

0

根據你在控制檯中的輸出,你在更新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 
+0

當我做出前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

+0

1.我錯過了這個部分,在沒有評論的時候,你應該在商業#節目上做@ @ business.reviews.build'。 2.更新的'ArgumentError'可能由'@ review.update(params [review_params])'的代碼引起。我認爲應該更改爲'@ review.update(review_params)' – 2014-08-29 16:25:04

+0

該修復允許編輯評論,假設我使用了正確版本的表單。如果我使用'[@business,@ business.reviews.build]'版本,點擊'編輯'會創建一個新的評論。如果我將其更改爲'[@business,@review]'版本,然後點擊'編輯',則表單將被預填充並正確更新。但是,如果我使用這個版本,我甚至無法進入商業#show。我得到了前面提到的第一個錯誤。這就是爲什麼一旦我登陸商業#展會就要改變它。這就像需要表單的兩個版本。我錯過了什麼?這不就是爲什麼我們首先使用偏分量嗎? – 2014-08-29 17:14:19

相關問題