1

在我的Rails 3項目中,通過跟隨模型,我有一個帶有自引用連接的用戶模型。我想使用這個連接表來查找跟隨用戶相關的活動。除了由連接生成的查詢完全忽略連接模型上的primary_key選項外,幾乎所有設置都正確。has_many:通過with:primary_key在連接表上不起作用

下面是相關機型的相關模式:

create_table "users", :force => true do |t| 
    t.string "email",         :default => "", :null => false 
    t.string "first_name" 
    t.string "last_name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "follows", :force => true do |t| 
    t.integer "user_id" 
    t.integer "followed_user_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "activities", :force => true do |t| 
    t.integer "user_id" 
    t.text  "body" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

下面是該機型

class User < ActiveRecord::Base 
    has_many :follows 
    has_many :followed_users, :through => :follows 
    has_many :followed_activities, :through => :follows 
    has_many :activities 
end 
class Follow < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :followed_user, :class_name => "User" 
    has_many :followed_activities, :primary_key => :followed_user, :foreign_key => :user_id, :class_name => "Activity" 
end 

下面的工作就好了關聯:

u = User.first 
u.follows # returns corresponding records from the follows table 
u.followed_users # returns all users that u is following 
u.followed_users.first.activities # returns all activity records corresponding to the first person the user is following 
Follow.first.activities # same as the previous 

然而,以下僅返回一個空數組:

u.followed_activities 

這裏是從最後一條語句生成的SQL:

Activity Load (0.2ms) SELECT `activities`.* FROM `activities` INNER JOIN `follows` ON `activities`.user_id = `follows`.id WHERE ((`follows`.user_id = 1)) 

它不工作的原因是因爲它正在嘗試加入使用「follows'.id作爲主鍵,而比'follow'.followed_user。

這是一個錯誤,還是我必須在用戶模型的某個地方重複:primary_key聲明?我無法在Rails api中的任何地方找到任何提及,也無法在網上找到其他地方。

Rails的版本:3.0.7

回答

0

賈斯汀,你有2個名爲「followed_activities」的關聯。當然,他們有不同的上下文(不同型號),但我想請你嘗試這樣的關聯塊中的方法:

has_many :followed_users, :through => :follows do 
    def activities 
    end 
end 
+0

在兩個模型中擁有「followed_activities」的好處。我只把關聯放在跟隨模型中,因爲這是我唯一可以弄清楚如何得到我的has_many的方法:通過關聯來工作(我無法得到source聲明在這裏工作)。正如你所提到的,我正在努力研究如何使它與關聯塊一起工作。我會在這個區塊內放什麼?尋找方法? – Justin

+0

是的,finder方法或迭代器,如果你想收集一個數組。最初的想法是在本書中有關聯的方法[Advanced Rails Recipes](http:// pragprog。com/book/fr_arr/advanced-rails-recipes) – Anatoly

+0

我忘了我有這本書!使用本書中的另一個技巧,我略微闡述了這個想法。我無法弄清楚如何在評論中做到這一點,所以我已經更新了你的文章。 – Justin

1

我發現它直觀的以菊花鏈關係與「nested_has_many_through」寶石,http://rubygems.org/gems/nested_has_many_through這將是軌道3.1的標準組成部分,可以給你另一種工具來解決這裏

問題它可以讓你做這樣的事情:

class Author < User 
    has_many :posts 
    has_many :categories, :through => :posts, :uniq => true 
    has_many :similar_posts, :through => :categories, :source => :posts 
    has_many :similar_authors, :through => :similar_posts, :source => :author, :uniq => true 
    has_many :posts_of_similar_authors, :through => :similar_authors, :source => :posts, :uniq => true 
    has_many :commenters, :through => :posts, :uniq => true 
end 

class Post < ActiveRecord::Base 
    belongs_to :author 
    belongs_to :category 
    has_many :comments 
    has_many :commenters, :through => :comments, :source => :user, :uniq => true 
end 

這超級簡化我的查詢和集合。我希望你找到你的問題的答案,這是一個艱難的!

+0

如果給沒有其他選擇,我會嘗試使用菊花方法鏈接我的查詢你描述了(user.followed_users.activities),但是我構建它的方式只有一個簡單的has_many:through。唯一的區別是我在連接表上使用了一個非標準的primary_key。 – Justin

+0

不錯,謝謝!我不知道他們已經將此添加到3.1。 has_many - >:through - >:source正是我需要使我的複雜查詢工作而不訴諸海量SQL語句的原因。 – poetmountain

相關問題