Rails Formtastic嵌套表单 - 来自连接模型的属性表单

时间:2012-01-07 12:01:32

标签: ruby-on-rails forms nested-forms formtastic nested-attributes

我面临Formtastic的问题是我有一个表单来创建新的Order。在此表单中,我想从列表中选择多个现有的Food项。这些应添加到我提交的新订单中。同时我还想在FoodOrder连接模型中设置属性。此模型具有整数数量属性,我希望在我的表单中有一个字段。

我基本上寻找的是一个列出所有食物项目的表单,并将quantity的字段放在与它所属的食物项目相同的行上。

模特

class Order < ActiveRecord::Base
  belongs_to :user
  belongs_to :restaurant
  has_many :food_orders
  has_many :foods, :through => :food_orders
end

class FoodOrder < ActiveRecord::Base
  belongs_to :food
  belongs_to :order
end

class Food < ActiveRecord::Base
  has_many :food_orders
  has_many :orders, :through => :food_orders
  belongs_to :category
end

这是我到目前为止尝试过的表单版本之一。但我感到困惑,不知道如何获得FoodOrder模型的字段。

<%= semantic_form_for [@restaurant, @order] do |f| %>
  <%= f.inputs do %>
    <%= f.input :comment %><br />
    <%= f.input :table_id %><br />
    <%# <%= f.input :foods, :as => :check_boxes %>
    <%= f.inputs :for => :foods do |food| %>
      <%= food %>
      <%= food.inputs :quantity %>
    <% end %>
  <% end %>
  <%= f.buttons do %>
    <%= f.commit_button %>
  <% end %>
<% end %>

我的模特有这些属性

create_table "food_orders", :force => true do |t|
  t.integer  "quantity",   :null => false
  t.decimal  "price",      :null => false
  t.integer  "food_id",    :null => false
  t.integer  "order_id",   :null => false
  t.text     "comment"
  t.datetime "created_at", :null => false
  t.datetime "updated_at", :null => false
end

create_table "foods", :force => true do |t|
  t.integer  "category_id",                     :null => false
  t.string   "name",                            :null => false
  t.string   "description"
  t.string   "image"
  t.decimal  "default_price",                   :null => false
  t.boolean  "active",        :default => true, :null => false
  t.datetime "created_at",                      :null => false
  t.datetime "updated_at",                      :null => false
end

create_table "orders", :force => true do |t|
  t.integer  "restaurant_id",                    :null => false
  t.integer  "user_id",                          :null => false
  t.integer  "table_id",                         :null => false
  t.decimal  "total",                            :null => false
  t.datetime "finished_at"
  t.datetime "created_at",                       :null => false
  t.datetime "updated_at",                       :null => false
end

1 个答案:

答案 0 :(得分:0)

基本上我最终要做的是为每个FoodOrder创建一个Food对象,然后只保存值大于0的对象。

您可以reject_ifaccepts_nested_attributes_for执行此操作但不会删除有人可能从3更改为0的旧FoodOrder。所以相反,您必须覆盖quantity=的{​​{1}}方法。

我之前从未使用FoodOrder,但我会猜测并说这应该有效。

formtastic

order.rb:

<%= semantic_form_for [@restaurant, @order] do |f| %>
  <%= f.inputs do %>
    <%= f.input :comment %><br />
    <%= f.input :table_id %><br />
    <% @foods.each do |food|
      <%= f.semantic_fields_for :food_orders, 
                            @order.food_orders.detect_or_build_by_food(food)
                            do |food_order| %>
        <%= food %>
        <%= food_order.inputs :quantity %>
      <% end %>
    <% end %>
  <% end %>
  <%= f.buttons do %>
    <%= f.commit_button %>
  <% end %>
<% end %>

food_order.rb:

class Order < ActiveRecord::Base
  belongs_to :user
  belongs_to :restaurant
  has_many :foods, :through => :food_orders
  has_many :food_orders do
    def detect_or_build_by_food(food)
      record = self.detect{ |food_order| food_order.food_id == food.id }
      if record.nil?
        record = self.build(:food => food)
      end
      record
    end
  end

  accepts_nested_attributes_for :food_orders
end

我希望它有效,但它是未经测试的代码,所以是的...祝你好运!