我正在将应用程序从 php 转换为 rails,并且我仍在学习有关 rails 和 AR 的方法。
简单地说:我想列出当前用户还不是成员的组。
失败的方法:
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)
- 还有很多...
谢谢你的帮助!
关于模型的一些信息
用户.rb(片段)
has_many :cause_user_memberships
has_many :causes, :through => :cause_user_memberships
原因.rb
attr_accessible :title, :location, :description,...
has_many :cause_user_memberships
has_many :users, :through => :cause_user_memberships
Cause_User_Membership.rb(<--可能不是我最好的模型名称)
# == 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 个查询结果,一个包含我打算使用的地理编码器 gem,另一个不包含。如果有点乱,请见谅。)
在 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)