2016-04-12 4 views
2

Ich habe diese Modelle:Hat viele durch: Wie Datensatz hinzufügen und füllen Felder in Join-Tabelle

class Item < ActiveRecord::Base 
    has_many :users, through: :user_items 
    has_many :user_items 
end 

class User < ActiveRecord::Base 
    has_many :items, through: :user_items 
    has_many :user_items 
end 

class UserItem < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :item 
end 

create_table "user_items", force: :cascade do |t| 
    t.integer "user_id", 
    t.integer "item_id", 
    t.integer "amount" 
end 

Ich möchte die besten Möglichkeiten, wissen, ein Element für einen Benutzer ein ebenfalls gesetzt eine Menge hinzufügen in der Join-Tabelle.

Ich war so etwas wie dies zu tun:

user = User.first 
item = Item.first 
UserItems.create(user: user, item: item, amount: 5) 

aber ich es nicht so sehr mögen, und manchmal ist es nicht richtig funktionieren, denn wenn ich

user.items #=> [] 

betreibe ich bekommen leeres Array, scheint es nicht die neuen Änderungen in DB zu bekommen.

Also, gibt es eine einfache Möglichkeit, das zu tun? etwas intuitiv wie dies wäre perfekt:

user.user_items << item, amount: 4 

Ok, so habe ich auf diese Weise, und es funktionierte:

user.user_items.create!(item: item, amount: 5) 

aber auf diese Weise tat es nicht:

user.user_items << item, amount: 4 

Jetzt ist es eleganter. Aber ich habe immer noch das Problem mit der Caching-Anfrage. Wenn ich user.items ausführe. es ist immer noch leer. Irgendeine Idee? Ich habe versucht mit inverse_of und nichts. Ich möchte das Reload oder einige Methoden wie diese vermeiden. Ich möchte in einer transparenten Art und Weise tun, wenn es möglich ist,

+0

'benutzer.items.reload'? Ich meine, alles ist perfekt gespeichert, 'user.items' gibt wegen Caching ein leeres Array zurück. – mudasobwa

+0

Ich würde mich persönlich für diese SO Antwort (http://stackoverflow.com/questions/31982343/elegantly-set-join-table-attributes-on-has-my-through-association) entscheiden, die Ihnen alles geben würde, was Sie brauchen (einschließlich der Einstellung des Betrags). Ansonsten können Sie es immer noch in zwei Zeilen machen. – born4new

+0

@mudasobwa, ja, das ist richtig, alles ist perfekt gespeichert. Aber ich denke, es ist keine gute Übung, wenn ich 'reload' schreiben muss, findest du nicht? Deshalb suche ich nach einer sauberen Art, dies zu tun. Vielen Dank! – Quin

Antwort

1

Sie können diese wie tun:

user = User.first 
item = Item.first 
user.user_items.create!(item_id: item.id, amount: 5) 

oder:

user.items.push(items) 
+0

Ich denke, die erste könnte funktionieren, aber wie stellen Sie den Betrag Wert in der zweiten ein? Danke! – Quin

+0

@quin yeah zweite wird nur Elemente für Benutzer ohne Betrag hinzufügen.Wenn Sie Menge hinzufügen auch 'user.user_items.push (item_id: item.id, Betrag: 5)' –

0

Versuchen Sie, diese

user.user_items.push(item: item, amount: 5) 

Oder wenn Sie Artikel reflektieren möchten, ohne neue Werte zu drücken, versuchen Sie

UserItem.create(user: user, item: item, amount: 5) 
user.reload 
user.items # this will reflect newly loaded values now 
Verwandte Themen