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 является массив идентификаторов продуктов, которые вы хотите добавить в заказ, вы можете попробовать назначая их следующим образом и Рельсы должны автоматически создавать эти ассоциации записи для 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

  • Но как взять один идентификатор продукта из каждой части? Потому что теперь я могу выбрать только один продукт из всех

Вид:

= 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]) –