2016-07-03 11 views
0

Assoziationen sind meine Schienen Achilles Ferse.Wie Assoziationen von Schienen Konsole

Ich habe 3 Modelle und Steuerungen: User, List, Item.

Benutzer können username und password erstellen. Liste kann Liste erstellen name, Artikel kann erstellt werden item_name

Idealerweise gehört eine Liste einem Benutzer. Ein Artikel gehört zu einer Liste. Liste hat viele Gegenstände. Der Benutzer hat viele Listen. So kam ich mit:

class Item < ActiveRecord::Base 
    belongs_to :list 
    delegate :user, to: :list 
end 

class List < ActiveRecord::Base 
    belongs_to :user 
    has_many :items 
end 

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

Auf Schienen Konsole, nur um sicher zu machen, ich habe in die Spalten:

2.2.1 :005 > List.column_names 
=> ["id", "name", "user_id", "created_at", "updated_at"] 
2.2.1 :006 > Item.column_names 
=> ["id", "item_name", "list_id", "created_at", "updated_at"]  
2.2.1 :007 > User.column_names 
=> ["id", "username", "password", "created_at", "updated_at"] 

So ging ich neue Benutzer, Artikel zu erstellen, und List:

User.create(username: "iggy2", password: "helloworld") 
#let's say iggy2 has user_id 2. 

Ich möchte iggy2 haben eine Liste namens "wichtige Sachen", mit Artikel "Geschirr spülen".

Ich nahm an, dass Element mit Liste verbunden ist und Liste mit Benutzer verbunden ist. Aber wenn ich User.last.name eintippe, anstatt "Wichtig" zu sehen, bekomme ich eine NoMethodError: undefined method 'name'. Ich habe auch Ähnliche Fehler auf List.last.item_name

Dies ist, was mein Schema wie

create_table "items", force: :cascade do |t| 
    t.text  "item_name" 
    t.integer "list_id" 
    t.datetime "created_at",     null: false 
    t.datetime "updated_at",     null: false 
    end 

    create_table "lists", force: :cascade do |t| 
    t.string "name" 
    t.integer "user_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    create_table "users", force: :cascade do |t| 
    t.string "username" 
    t.string "password" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

sieht Was auf meinem Code fehlt? War meine Annahme falsch? Wie kann ich User.last.name oder sogar User.last.item_name erhalten, um den Namen oder den Listennamen des letzten Benutzers anzuzeigen?

Antwort

1

Ihr Code ist korrekt, aber Ihre Annahme ist falsch. User.last gibt einen Benutzerdatensatz zurück, sodass Sie beim Zugriff auf Methoden in verknüpften Datensätzen NoMethodError erhalten.

nehme ich an, was Sie wollen, ist unten:

List.where(user_id: User.last.id).pluck(:name) # Return all list names belong to last user 

id = List.find_by(user_id: User.last) 
Item.where(list_id: id).pluck(:item_name) # Return all item names belong to last user 
+0

Es funktionierte. Vielen Dank! Ich dachte nur an eine Folgefrage. Da ich immer noch Polymorphismus lerne, war ich mir nicht sicher, ob das möglich ist, aber ist es möglich, den Befehl User.last.item_name oder User.last.name (name = list name) zu haben und einen Wert zurückzugeben? (Das heißt, ist es möglich, direkt vom Benutzer zum Attribut eines anderen assoziierten Elements zu wechseln?), oder muss es den in der obigen Antwort erwähnten Prozess durchlaufen? Ich danke dir sehr! – Iggy

+0

sicherlich können Sie hier eine polymorphe Assoziation anwenden, dh 'Item' kann sowohl zu' User' als auch zu 'List' gehören. http://guides.rubyonrails.org/association_basics.html#polymorphic-associations sollte geben sollte gutes Beispiel geben – kasperite

Verwandte Themen