2016-07-03 8 views
0

アソシエーションはアキレス腱です。コンソールからアソシエーションを表示する方法

私は3モデルとコントローラ:User,List,Itemがあります。

ユーザーはusernamepasswordを作成できます。リストはリストnameを作成できます。アイテムは作成可能ですitem_name

理想的には、リストはユーザーに属しています。アイテムはリストに属します。リストには多くのアイテムがあります。ユーザーには多数のリストがあります。だから私が思いついた:念のため、レールコンソールで

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 

、私は列をチェックする:

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"] 

だから私は、新しいユーザー、アイテム、およびリストを作成するために行ってきました:

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

iggy2に「重要なもの」という名前の「皿洗い」という項目があります。

List.create(name: "Important", user_id: 2) #let's say this has id of 1 

Item.create(item_name: "Wash dishes", list_id: 1) 

アイテムがリストに接続され、リストがユーザーに接続されていると想定しました。しかし、「重要」と表示されずにUser.last.nameと入力すると、NoMethodError: undefined method 'name'と表示されます。私はまた、これは私のスキーマは私のコードに欠けている何

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 

のように見えるものであるList.last.item_name

に同様のエラーを取得しますか?私の仮定は間違っていたのですか?最後のユーザーのアイテム名またはリスト名を表示するには、User.last.name、さらにはUser.last.item_nameを取得するにはどうすればよいですか?

答えて

1

あなたのコードは正しいですが、あなたの前提が間違っています。 User.lastはユーザーレコードを返します。関連付けられたレコードのメソッドにアクセスするときはNoMethodErrorになります。

私が何をしたいことは以下であると仮定します

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

それは働きました。ありがとうございました!私はちょうどフォローアップの質問を考えた。私はまだ多型を学んでいるので、可能かどうかは確かではありませんでしたが、コマンドUser.last.item_nameまたはUser.last.name(name = list name)を持ち、値を返すことは可能ですか? (つまり、ユーザーから別の関連するアイテムの属性に直接移動することは可能ですか?)、または上記の答えに記載されているプロセスを経なければなりませんか?どうもありがとうございます! – Iggy

+0

ここで多相関連を適用することができます。つまり、 'Item'は' User'と 'List'の両方に属することができます。 http://guides.rubyonrails.org/association_basics.html#polymorphic-associationsはよい例を与えるべきである – kasperite

関連する問題