0

我已经设置has_many和has_many:通过Order,User,Product和Order_detail模型之间的关联作为连接表。Rails - has_many:通过关联+保存关联数据

型号:

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 

如何自动连接表ORDER_DETAILS保存。 现在数据只保存到订单表中。 需要保存所有产品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 
+1

您可能需要[nested_attributes(http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods。html)为这个 –

回答

-1

更改我的联想类型的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 
1

在您看来,加个领域像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 
    ]) 
1

假设product_ids是要添加到订单的产品ID的数组,你可以尝试下面的方式来进行分配和Rails的应该会自动创建ORDER_DETAILS这些协会的记录,当你再调用@ order.save

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

thk!我编辑了一些东西,需要建议 –

0

我说得对补充的是,控制器行? 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种不同类型的产品保存。

product_details

  • 但如何把一个产品ID从每个零件?因为现在我可以选择从所有

仅查看一个产品:

= 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" 
+1

我无法帮助simple_form的东西,但一看就知道控制器应该稍微改变一点。 order.products = Product.find_by_id(order_params [:product_ids])不会工作,因为@ order.products是一个集合。更改=为<< – hypern

+1

同样在您的强参数中,您可能需要将.permit(:date,order_details:[:product_id])更改为.permit(:date,order_details:[product_ids:[]]) – hypern

+0

push和< <相同(相等)的东西? order.products.push Product.find_by_id(order_params [:product_ids])order.products << Product.find_by_id(order_params [:product_ids]) –

相关问题