2016-12-14 52 views
0

我有产品带有一些参数(price,category_id,image等)的模型。Rails对象在创建时会丢失参数值

以部分形式创建新产品时,通过select_tag选择类别,图像通过Carrierwave,图像上传器上传。当我发送用户在crop.html.erb文件中裁剪上传的图像时,会发生不好的事情。有用户裁剪图像,点击提交,它使用路径作为更新(不太确定哪个HTTP协议),并且被重定向到产品编辑页面,因为产品以某种方式丢失了category_id参数。表单显示错误以选择一个类别(来自input_fields的所有其他参数不会丢失)。

我尝试像定义crop方法和设置有分类,但没有运气...

products_controller.rb:

def edit 
    @categories = Category.all 
    end 

    def create 
    @product = Product.new(product_params) 
    @product.category_id = params[:category_id] 
    @product.user_id = current_user.id 

    respond_to do |format| 
     if @product.save 
     if params[:product][:image].present? 
      format.html { render :crop } 
     else 
      format.html { redirect_to @product, notice: 'Product was successfully created.' } 
      format.json { render :show, status: :created, location: @product } 
     end 
     else 
     format.html { render :new } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    def update 
    @product.category_id = params[:category_id] 

    respond_to do |format| 
     if @product.update(product_params) 
     if params[:product][:image].present? 
      format.html { render :crop } 
     else 
      format.html { redirect_to @product, notice: 'Product was successfully updated.' } 
      format.json { render :show, status: :ok, location: @product } 

      @products = Product.all 
      ActionCable.server.broadcast 'products', 
      html: render_to_string('store/index', layout: false) 
     end 
     else 
     format.html { render :edit } 
     format.json { render json: @product.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

crop.html.erb(在产品中的文件夹):

<%= image_tag @product.image_url(:large), id: "cropbox" %> 

<h4>Preview</h4> 
<div style="width:300px; height:200px; overflow:hidden;"> 
    <%= image_tag @product.image.url(:large), :id => "preview" %> 
</div> 

<%= form_for @product do |f| %> 
    <% %w[x y w h].each do |attribute| %> 
    <%= f.hidden_field "crop_#{attribute}" %> 
    <% end %> 
    <div class="actions"> 
    <%= f.submit "Crop" %> 
    </div> 
<% end %> 

我还没有尝试设置存储category_id的回调,但我不知道它会是一个好主意吗?任何帮助?谢谢!

编辑 - 还加入了形式部分,但它工作正常 - 只为你的好奇心:

<%= form_for(product, hmtl: { multipart: true }) do |f| %> 
... 
    <div class="field"> 
    <%= f.label :category %> 
    <%= select_tag(:category_id, options_from_collection_for_select(Category.all, :id, :name, @product.category_id), include_blank: "Select Category") %> 
    </div> 

UPDATE

记录这些动作:

Started GET "/products/new" for ::1 at 2016-12-15 09:03:31 +0200 
Processing by ProductsController#new as HTML 
    [1m[36mCart Load (0.4ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mUser Load (2.0ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]] 
    Rendering products/new.html.erb within layouts/application 
    [1m[36mCategory Load (0.4ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m 
    Rendered products/_form.html.erb (6.2ms) 
    Rendered products/new.html.erb within layouts/application (11.2ms) 
    [1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m 
    [1m[36mLineItem Load (0.5ms)[0m [1m[34mSELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = $1[0m [["cart_id", 5]] 
Completed 200 OK in 127ms (Views: 113.2ms | ActiveRecord: 3.3ms) 


Started POST "/products" for ::1 at 2016-12-15 09:03:40 +0200 
Processing by ProductsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"eWZuqL6AqcN8wknjEL115ax9uBnpY4b9eP0o2xN2aPntd61YKyc4Ym1lUgjV1YrXfZbPr57HANXy7Kz5swCtlg==", "product"=>{"title"=>"kj", "description"=>"kj", "image"=>#<ActionDispatch::Http::UploadedFile:0x007fe40ba4abe0 @tempfile=#<Tempfile:/var/folders/dn/zq9x2jkd4856kwhfj5gbz2tc0000gn/T/RackMultipart20161215-3987-1adfacs.png>, @original_filename="Screen Shot 2016-12-05 at 09.14.48.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"product[image]\"; filename=\"Screen Shot 2016-12-05 at 09.14.48.png\"\r\nContent-Type: image/png\r\n">, "price"=>"98", "quantity"=>"98"}, "category_id"=>"1", "commit"=>"Create Product"} 
    [1m[36mCart Load (0.3ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m [["id", 5], ["LIMIT", 1]] 
    [1m[36mUser Load (0.7ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m [["id", 1], ["LIMIT", 1]] 
    [1m[35m (0.3ms)[0m [1m[35mBEGIN[0m 
    [1m[36mCategory Load (0.3ms)[0m [1m[34mSELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 LIMIT $2[0m [["id", 1], ["LIMIT", 1]] 
    [1m[35mSQL (1.0ms)[0m [1m[32mINSERT INTO "products" ("title", "description", "price", "quantity", "created_at", "updated_at", "category_id", "user_id", "image") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"[0m [["title", "kj"], ["description", "kj"], ["price", #<BigDecimal:7fe40ccf9110,'0.98E2',9(18)>], ["quantity", 98], ["created_at", 2016-12-15 07:03:41 UTC], ["updated_at", 2016-12-15 07:03:41 UTC], ["category_id", "1"], ["user_id", 1], ["image", "Screen_Shot_2016-12-05_at_09.14.48.png"]] 
    [1m[35m (3.1ms)[0m [1m[35mCOMMIT[0m 
    Rendering products/crop.html.erb within layouts/application 
    Rendered products/crop.html.erb within layouts/application (3.1ms) 
    [1m[36mCategory Load (0.7ms)[0m [1m[34mSELECT "categories".* FROM "categories"[0m 
    [1m[36mLineItem Load (0.3ms)[0m [1m[34mSELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = $1[0m [["cart_id", 5]] 
Completed 200 OK in 957ms (Views: 127.8ms | ActiveRecord: 6.7ms) 

所以我注意到它会呈现products/crop.html.erb而没有特定的ID,所以我在我的路线中添加了:

resources :products do 
    get 'crop', on: :member 
    end 

而且products_controller创建行动:

... 
    respond_to do |format| 
     if @product.save 
     if params[:product][:image].present? 
      format.html { render crop_product_path(@product) } 
     else 
... 

仍是同样的错误,一个类别必须选择。 并注意 - 如果只是去编辑产品(但不是从crop行动),类别坐在那里,因为假设...

+0

尝试在你的'crop.html'加入'hidden_​​field'为'category_id'收到category_id服务器上视图。并将其设置为“@ product.category_id”。然后你可以稍后检索'update'动作中的值 – Kkulikovskis

+0

Hm,漂亮的catch,但是然后我得到'undefined method {:category_id =>“1”}''...试图在产品控制器中的作物动作中定义产品。 ..隐藏字段:'<%= f.hidden_​​field:category_id => @ product.category_id%>' –

+1

如果您将隐藏的字段置于表单中,它将置于'product'下,以便在更新操作中获取category_id,它将成为在'params [:product] [:category_id]' – Kkulikovskis

回答

1

由于窗体只提交收集它定义的参数,你应该添加一个隐藏现场设置category_idcrop.html视图

<%= image_tag @product.image_url(:large), id: "cropbox" %> 

<h4>Preview</h4> 
<div style="width:300px; height:200px; overflow:hidden;"> 
    <%= image_tag @product.image.url(:large), :id => "preview" %> 
</div> 

<%= form_for @product do |f| %> 
    <% %w[x y w h].each do |attribute| %> 
    <%= f.hidden_field "crop_#{attribute}" %> 
    <% end %> 
    <%= f.hidden_field :category_id %> 
    <div class="actions"> 
    <%= f.submit "Crop" %> 
    </div> 
<% end %> 

现在,当您提交表单,您将在params[:product][:category_id]