Rails多个带有关联文本字段的复选框

时间:2018-04-18 07:24:10

标签: ruby-on-rails has-many-through active-form

我正在尝试创建一个产品表单,其中包含每种尺寸的多种尺寸和价格。

我建模的方式是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 %>

1 个答案:

答案 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创建价格,
    并将ProductDetailSize
  • 相关联

现在,您可以使用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 %>

我的代码完全没有经过测试,你仍然有许多事情要做,但它应该是解决问题的正确方法。 您可以考虑清单来完成它:

  • 显示尺寸名称。例如:XL,XXL
  • 允许正确的参数
  • 拒绝无效的CakeDetail属性集。
  • 更新时避免重复产品尺寸

&LT;&LT;更新&gt;&gt;&gt;

由于check_box仅生成01值,因此将其用于size_id是不正确的。我们可以通过以下方式解决:

  • attr_accessor添加is_enable(例如:CakeDetail)并将其用于check_box
  • size_id成为隐藏的字段
  • 如果is_enable != 1
  • 则拒绝属性

您可以在此处找到一个工作示例yeuem1vannam/product-size