我正在尝试创建一个产品表单,其中包含每种尺寸的多种尺寸和价格。
我建模的方式是has_many:通过关系。 关联表包含一个额外的价格字段,现在它将包含product_id,size_id和price。
我不确定如何创建表单或Rails希望如何看待它。任何帮助将不胜感激。
我的产品是蛋糕:))
class Cake < ApplicationRecord
belongs_to :cake_type
has_many :cake_details
has_many :sizes, through: :cake_details
end
尺寸模型
class Size < ApplicationRecord
has_many :cake_details
has_many :cakes, through: :cake_details
end
CakeDetail模型 class CakeDetail&lt; ApplicationRecord belongs_to:蛋糕 belongs_to:size 端
我的迁移
class CreateCakeDetails < ActiveRecord::Migration[5.1]
def change
create_table :cake_details do |t|
t.references :cake, foreign_key: true
t.references :size, foreign_key: true
t.decimal :price, :precision => 10, :scale => 2
t.timestamps
end
end
end
我唯一坚持的是将表单与模型联系起来。 即,对于每种尺寸,我都希望有一个价格相关的文本框。
目前我正在接近它,但我不知道rails希望文本框的内容如何显示或我应该如何构建它。
目前我正在以我的形式进行实验
<%= collection_check_boxes(:cake, :size_ids, Size.all, :id, :name) do |b| %>
<tr>
<td>
<%= b.label %>
</td>
<td>
<%= b.check_box %>
</td>
<td>
<%= form.text_field :cake_detail, id: b.label %>
</td>
</tr>
<% end %>
答案 0 :(得分:0)
您定义业务逻辑的方式是正常的
- A product has multiple sizes
- Each size has a price
我认为唯一可以解决问题的是你想要同时创建所有内容。即使Rails有nested_attributes
这可能会解决你的问题,但让我们再一次思考
通常,Size
记录是固定的并且是事先创建的。因此,您不必在创建Product
的同时创建它
一旦你处理了这个想法,你的问题就变得容易了:
Size
的列表:M,L,XL,XXL ......是事先创建的
(您可以通过db/seeds.rb
)Product
沿着ProductDetail
创建价格,ProductDetail
与Size
现在,您可以使用Rails nested_attributes
作为关系Product -> ProductDetail
你的模特
# app/models/cake.rb
class Cake < ApplicationRecord
belongs_to :cake_type
has_many :cake_details
has_many :sizes, through: :cake_details
attr_accessor :is_enable
accepts_nested_attributes_for :cake_details, reject_if: :is_not_good_detail?
private
def is_not_good_detail?(attributed)
return true if attributed[:is_enable].to_i != 1
# Check if CakeDetail is good or not
end
end
您的控制器
# app/controllers/cakes_controller.rb
class CakesController < ApplicationController
def new
@cake = Cake.new
# Build `cake_details`, so that you can render them at view
Size.each do |size|
@cake.cake_details.build(size_id: size.id, price: 0)
end
end
def create
# Create your Cake + CakeDetail
end
private
def cake_params
# permit your params here
end
end
您的观点
# app/views/cakes/_form.html.erb
<%= form_for @cake do |f| %>
<%= f.fields_for :cakes_detail do |field| %>
<%= field.check_box :is_enable %>
<%= field.hidden_field :size_id %>
<%= field.text_field :price %>
<% end>
<% end %>
我的代码完全没有经过测试,你仍然有许多事情要做,但它应该是解决问题的正确方法。 您可以考虑清单来完成它:
由于check_box
仅生成0
和1
值,因此将其用于size_id
是不正确的。我们可以通过以下方式解决:
attr_accessor
添加is_enable
(例如:CakeDetail
)并将其用于check_box
size_id
成为隐藏的字段is_enable != 1
您可以在此处找到一个工作示例yeuem1vannam/product-size