Rails - has_many :通过关联+保存关联数据

Rails - has_many :through association + save data for association

我设置了 has_many 和 has_many:通过订单、用户、产品和 Order_detail 模型之间的关联作为连接 table。

型号:

class Order < ActiveRecord::Base
  has_many :order_details
  belongs_to :user
  has_many :products, through: :order_details
end

class OrderDetail < ActiveRecord::Base
  belongs_to :order
  belongs_to :product
end

class Product < ActiveRecord::Base
  has_many :order_details
  has_many :orders, through: :order_details
end

class User < ActiveRecord::Base
  has_many :orders
end

如何为加入 table order_details 自动保存。 现在数据只保存到订单 table。 需要将当前订单和用户

的所有产品保存到order_tables
class OrdersController < ApplicationController
  before_action :authenticate_user!

  def index
    @order = Order.all
  end

  def new
    # @order = Order.new
    @order = current_user.orders.new
  end

  def create
    @order = current_user.orders.new(order_params)
    @order.date = Date.today.to_s
    if @order.save
       # i think this is bad wrong to implementation of functional)
       # params[:product_id].each do |detail_product_id|
       # @order.order_details.product_id = detail_product_id
       # @order.order_details.user_id = current_user
       # @order.order_details.save
       flash[:success] = "Order was successfully submitted"
       redirect_to new_order_path
    else
      render :new
    end
  end

 private

 def order_params
   params.require(:order).permit(:date, :product_id => [])
 end
end

我的架构:

create_table "order_details", force: true do |t|
  t.integer  "order_id"
  t.integer  "product_id"
  t.integer  "quantity"
  t.integer  "price"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "orders", force: true do |t|
 t.integer "user_id"
 t.date    "date"
end

add_index "orders", ["user_id"], name: "index_orders_on_user_id", using: :btree

create_table "orders_products", id: false, force: true do |t|
  t.integer "order_id"
  t.integer "product_id"
end

create_table "products", force: true do |t|
  t.string   "product_name"
  t.integer  "product_price"
  t.datetime "created_at",       null: false
  t.datetime "updated_at",       null: false
  t.boolean  "available_status"
  t.string   "product_type"
end

在您看来,为 order_details 添加字段,例如:

     <%= f.fields_for :order_details do |od| %>
       <%= od.label 'your attribute for OrderDetail' %>
       <%=  # od.text_field 'your attribute' %>
     <% end %>

然后在您的模型中,接受 order_details 的嵌套属性 喜欢:

    accepts_nested_attributes_for :order_details

这些是示例值,您可以将此逻辑用于您的实际属性。

在您的控制器中,允许 order_details 的属性,例如:

    params.require(:order).permit(:id, :name, order_details: [
      #attributes of order details
    ])

假设 product_ids 是您希望添加到订单中的产品 ID 数组,您可以尝试按以下方式分配它们,并且 Rails 应该会自动创建这些关联记录order_details 然后调用@order.save

@order.products << Product.find_by_id(product_ids)

我为控制器添加的行是否正确? Order_controller:

  def create
    @order = current_user.orders.new(order_params)
    @order.products = Product.find_by_id(order_params[:product_ids])
    @order.date = Date.today.to_s
    if @order.save
      flash[:success] = "Order was successfully submitted"
      redirect_to new_order_path
    else
      render :new
    end
  end

 private
 def order_params
   params.require(:order).permit(:date, order_details: [:product_id])
 end
end

订购型号:

  accepts_nested_attributes_for :order_details

我正在尝试从 3 种不同类型的产品中节省开支。

  • 但是如何从每个零件中取一个产品编号呢?因为现在我只能从所有产品中选择一种

查看:

= simple_form_for(@order, html: {:class => 'well form-horizontal', :method  => :post, :action=> :create }) do |f|
    .col-xs-12.col-sm-6.col-md-8
    = render 'shared/error_messages', object: f.object
    %br
    = simple_fields_for :order_details do |od|
       = od.collection_radio_buttons :product_ids, Product.get_first_course, :id, :product_name ,:item_wrapper_class => 'inline'
      %hr
      = od.collection_radio_buttons :product_ids, Product.get_main_course, :id, :product_name, :item_wrapper_class => 'inline'
      %hr
      = od.collection_radio_buttons :product_ids, Product.get_drink, :id, :product_name,:item_wrapper_class => 'inline'
     %hr
   = f.button :submit, class: "btn btn-primary"

我将关联类型更改为 HABTM,这足以满足我的情况。所以..

型号:

  class Order < ActiveRecord::Base
   has_and_belongs_to_many :products
   before_destroy { products.clear }
  end
  class Product < ActiveRecord::Base
   has_and_belongs_to_many :orders
  end

Order_controller:

def create
  order = current_user.orders.new(date: Date.today.to_s)
  @order_products = Product.where(id: order_params[:product_ids])
  order.products << @order_products
  if order.save
    #blalblal - sucsess
  else
    #blabla - alert-notice
  end