Rails 对象在创建时失去参数值
Rails object loses params value while creating it
我有 Product 模型和一些参数(价格、category_id、图片等)。
当以部分形式创建新产品时,类别正在通过 select_tag
进行 select 编辑,图像通过图像上传器 Carrierwave 上传。当我让用户在 crop.html.erb
文件中裁剪上传的图像时,会发生不好的事情。用户裁剪图像,点击提交,使用路径作为更新(不太确定是哪个 HTTP 协议),并被重定向到产品编辑页面,因为产品不知何故丢失了 category_id
参数。表单向 select 类别显示错误(来自 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>
更新
这些操作的日志:
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" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mUser Load (2.0ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [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" = [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" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mUser Load (0.7ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [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" = LIMIT [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 (, , , , , , , , ) 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" = [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
...
仍然是同样的错误,一个类别必须 selected。
并且要注意 - 如果只是去编辑产品(而不是从 crop
操作),类别就在那里......
由于表单仅提交其中定义的收集的参数,您应该添加一个隐藏字段来设置 category_id
在 crop.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]
后在服务器上收到 category_id
我有 Product 模型和一些参数(价格、category_id、图片等)。
当以部分形式创建新产品时,类别正在通过 select_tag
进行 select 编辑,图像通过图像上传器 Carrierwave 上传。当我让用户在 crop.html.erb
文件中裁剪上传的图像时,会发生不好的事情。用户裁剪图像,点击提交,使用路径作为更新(不太确定是哪个 HTTP 协议),并被重定向到产品编辑页面,因为产品不知何故丢失了 category_id
参数。表单向 select 类别显示错误(来自 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>
更新
这些操作的日志:
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" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mUser Load (2.0ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [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" = [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" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mCACHE (0.0ms)[0m [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = LIMIT [0m [["id", 5], ["LIMIT", 1]]
[1m[36mUser Load (0.7ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [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" = LIMIT [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 (, , , , , , , , ) 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" = [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
...
仍然是同样的错误,一个类别必须 selected。
并且要注意 - 如果只是去编辑产品(而不是从 crop
操作),类别就在那里......
由于表单仅提交其中定义的收集的参数,您应该添加一个隐藏字段来设置 category_id
在 crop.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]
category_id