2

I want the user to search through existing items from the items table in the orders form, it works for clients but not for items, it gives an error: Association :item not found

Models

class Order < ActiveRecord::Base
    belongs_to :user
    belongs_to :client

    has_many :order_items
    has_many :items, :through => :order_items
end

class Item < ActiveRecord::Base
    has_many :order_items
    has_many :orders, :through => :order_items
end

class OrderItem < ActiveRecord::Base
    belongs_to :item
    belongs_to :order
end

Migration

class CreateOrderItems < ActiveRecord::Migration
  def change
    create_table :order_items do |t|
        t.integer :item_id
        t.integer :order_id
      t.timestamps
    end
    add_index   :order_items, [:item_id, :order_id]
  end
end

View

<%= simple_form_for(@order) do |f| %>
  <%= f.error_notification %>
    <%= f.association :client, collection: Client.all, label_method: :name, value_method: :id, prompt: "Choose a Client", input_html: { id: 'client-select2' } %>
    <%= f.association :item, collection: Item.all, label_method: :name, value_method: :id, prompt: "Choose an item", input_html: { id: 'client-select2' }  %>
<%= f.input :memo, label: 'Comments' %>
    <%= f.submit %>
<% end %>

Controller

 def new
    @order = Order.new
  end

  def create
    @order = Order.new(order_params)
    @order.user_id = current_user.id
    @order.status = TRUE
  end
  def order_params
    params.require(:order).permit(:code, :client_id, :user_id, :memo, :status,    items_attributes: [:id, :name, :price, :quantity, :status, :_destroy])
  end

Answer

In the form use instead: using rails-select2 gem

<%= f.association :items, collection: Item.all, label_method: :name, value_method: :id, prompt: "Choose an item", input_html: { id: 'item-select2' } %>

or without select2

<%= f.select :item_ids, Item.all.collect {|x| [x.name, x.id]}, {}, multiple: true %>

Thanks to JKen13579

lightbots
  • 485
  • 3
  • 13
  • Why are you adding `has_many :order_items` and `has_many :items, :through => :order_items`? you should only add the second on AFAIK. – Tamer Shlash May 26 '14 at 18:00
  • Also `belongs_to :user` with `belongs_to :client` looks weird, isn't a user actually a client? – Tamer Shlash May 26 '14 at 18:02
  • I was referring to: [link](http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association) where they have the has_many, so I thought I would need it as well – lightbots May 26 '14 at 18:03
  • well the users are the employees who are creating the orders for clients. the clients do not touch the system. – lightbots May 26 '14 at 18:04
  • Aha I see, everything is fine regarding association logic then :) – Tamer Shlash May 26 '14 at 18:05

1 Answers1

3

The reason that you're receiving the error for item but not for client is because there is one client associated to an order, but more than one item associated to an order. It's saying :item not found because you should be using :items (note the plural).

To allow multi-select for your order's items, replace your f.association item line with:

<%= f.select :item_ids, Item.all.collect {|x| [x.name, x.id]}, {}, multiple: true %>

And then in your controller, be sure to permit item_ids. In addition, you don't need item_attributes, because you're not using accepted_nested_attributes_for :items.

def order_params
  params.require(:order).permit(:code, :client_id, :user_id, :memo, :status, item_ids: [])
end

See this SO answer for more information about has_many :through multi-select.

Community
  • 1
  • 1
Joe Kennedy
  • 9,365
  • 7
  • 41
  • 55
  • `:items` worked, no errors are showing but after I submit the form while items selected, the table `:order_items` still shows as empty – lightbots May 26 '14 at 18:38
  • Ah yes you're using strong parameters. It's it in [the SO answer I posted](http://stackoverflow.com/a/9917006/2856441), but I added it to my answer. Hopefully that solves it for you. – Joe Kennedy May 26 '14 at 19:17
  • Wonderful that worked. `<%= f.association :items, collection: Item.all, label_method: :name, value_method: :id, prompt: "Choose an item", input_html: { id: 'item-select2' } %>` Is what I used instead for multiselect with search (rails-select2 gem) – lightbots May 26 '14 at 19:21