我正在將應用程序從php轉換爲rails,而且我仍然在學習圍繞rails和AR的方式。我想列出當前用戶還不是成員的組。Rails 3 - 列出當前用戶還不是成員的組
失敗的方法:
Cause.select('causes.*').joins(:users).group('causes.id').where("cause_user_memberships.user_id NOT IN (?)", current_user.id)
Cause.select('causes.*').joins(:users).group('causes.id').where("cause_user_memberships.user_id NOT IN (SELECT cause_user_memberships.cause_id FROM cause_user_memberships WHERE cause_user_memberships.user_id =(?))", current_user.id)
- 還有更多...
感謝您的幫助!
約車型的一些信息
User.rb(片段)
has_many :cause_user_memberships
has_many :causes, :through => :cause_user_memberships
Cause.rb
attr_accessible :title, :location, :description,...
has_many :cause_user_memberships
has_many :users, :through => :cause_user_memberships
Cause_User_Membership.rb(< --probably不我最好的模特名字)
# == Schema Information
#
# Table name: cause_user_memberships
#
# id :integer not null, primary key
# user_id :integer not null
# cause_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
#
class CauseUserMembership < ActiveRecord::Base
attr_accessible :cause_id, :user_id
belongs_to :user
belongs_to :cause, :counter_cache => :users_count
accepts_nested_attributes_for :cause
validates_uniqueness_of :user_id, :scope =>[:cause_id]
end
更新:跟進
DERP,你是對的,它的工作!謝謝!
小跟進,查詢時間似乎很長。這是否表明存在問題?我在每張表中的記錄少於20條。 (下面是2個查詢結果,一個包含地理編碼寶石,我打算用,另一個不很抱歉,如果這是一個有些凌亂。)
在Rails控制檯:
Cause Load (1003.0ms) SELECT "causes".* FROM "causes" LEFT JOIN cause_user_memberships ON cause_user_memberships.cause_id = causes.id AND cause_user_memberships.user_id = 1 WHERE (cause_user_memberships.id IS NULL)
EXPLAIN (34.3ms) EXPLAIN SELECT "causes".* FROM "causes" LEFT JOIN cause_user_memberships ON cause_user_memberships.cause_id = causes.id AND cause_user_memberships.user_id = 1 WHERE (cause_user_memberships.id IS NULL)
查詢計劃
Hash Right Join (cost=10.45..37.99 rows=1 width=3168)
Hash Cond: (cause_user_memberships.cause_id = causes.id)
Filter: (cause_user_memberships.id IS NULL)
-> Seq Scan on cause_user_memberships (cost=0.00..27.50 rows=7 width=8)
Filter: (user_id = 1)
-> Hash (cost=10.20..10.20 rows=20 width=3168)
-> Seq Scan on causes (cost=0.00..10.20 rows=20 width=3168)
(7 rows)
隨着地理編碼本地主機上:
User Load (18.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Cause Load (49.6ms) SELECT causes.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((40.714269 - causes.lat) * PI()/180/2), 2) + COS(40.714269 * PI()/180) * COS(causes.lat * PI()/180) * POWER(SIN((-74.005972 - causes.lng) * PI()/180/2), 2))) AS distance, CAST(DEGREES(ATAN2(RADIANS(causes.lng - -74.005972), RADIANS(causes.lat - 40.714269))) + 360 AS decimal) % 360 AS bearing FROM "causes" LEFT JOIN cause_user_memberships
ON cause_user_memberships.cause_id = causes.id
AND cause_user_memberships.user_id = 1 WHERE (causes.lat BETWEEN 36.37231550667456 AND 45.05622249332544 AND causes.lng BETWEEN -79.73435509229111 AND -68.27758890770889 AND 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((40.714269 - causes.lat) * PI()/180/2), 2) + COS(40.714269 * PI()/180) * COS(causes.lat * PI()/180) * POWER(SIN((-74.005972 - causes.lng) * PI()/180/2), 2))) <= 300) AND (cause_user_memberships.id IS NULL) ORDER BY distance ASC
Completed 200 OK in 1068ms (Views: 49.1ms | ActiveRecord: 791.4ms)
左連接通常比內連接慢。通過在連接表上的'cause_id'和'user_id'列上應用索引,您可能會看到一些改進。在表示「Seq Scan」的查詢計劃中,這意味着postgres只是遍歷表,直到找到結果。 – patrickmcgraw
感謝您的建議。我今晚會做。 1000毫秒似乎不是太長?當我用php/MySQL做了幾乎相同的事情並且沒有活躍的記錄時,它將會更快。抓住我的頭爲什麼有這麼大的差異。 –
它似乎有點長。但是有很多變數。 ActiveRecord在內存中構建對象的副本,因此與查詢速度沒有直接關係的開銷較大。您可以在像pgAdmin這樣的SQL控制檯中檢查查詢,以便將ActiveRecord作爲變量移除。 – patrickmcgraw