在使用has_many:through时列出记录时获得重复

时间:2015-03-17 00:46:23

标签: ruby-on-rails activerecord

我有3个表:经理网站访问

目标

我希望能够以一种方式创建访问,当我找到有效的管理员和有效的网站时,我将创建一个有效的访问。

问题

当我尝试使用简单的 has_many:虽然关联时,我得到了一些意想不到的结果(我还没经常使用它)。

我已经这样设置了:

class Manager < ActiveRecord::Base
  has_many :sites, through: :visits
  has_many :visits
end 
class Site < ActiveRecord::Base
  has_many :managers, through: :visits
  has_many :visits
end 
class Visit < ActiveRecord::Base
  belongs_to :manager
  belongs_to :site
end 

我遇到的第一个问题是找到经理和网站的时候:

manager = Manager.find(3)
site = Site.find(5)

我创建了两次访问:

Visit.create(manager: manager, site: site)
Visit.create(manager: manager, site: site)

我按预期进行了2次访问:

manager.visits.count #2
site.visits.count #2

但我没有预料到,我不会为经理提供2个网站:

manager.sites.count #2

我希望manager.sites只返回一个网站,因为这位经理只访问过一个网站:/

问题2 是我无法弄清楚如何设置它以便按我描述的方式工作。我可能需要另一种型号,但我无法弄明白。

我在这里做错了吗?

有人能帮助我吗?

2 个答案:

答案 0 :(得分:0)

也许您应该将计数器列添加到Visit,而不是为每次访问创建新行,您只需使用x = Visit.find_or_create_by(~manager, ~site); x.counter.increment; (in schema counter should default to 0)之类的内容。而不是为每个(或范围)定义has_many :visits,并像Manager.visits.where(~search by site).counter一样访问,它会为您提供总访问次数。

答案 1 :(得分:0)

uniq 来救援。

这是very undocumented方法。它将DISTINCT添加到SQL SELECT。

改变两者:

has_many :managers, through: :visits
has_many :sites, through: :visits

has_many :managers, ->{ uniq }, through: :visits
has_many :sites, ->{ uniq }, through: :visits

给了我正在寻找的行为!

我遇到的另一个问题,解决得更快:

当我列出访问特定网站的管理员时,我得到了重复。

Manager.all.joins(:sites).merge(Site.where(site_token: "..."))

要解决此问题,我必须在 .joins(...)

之后添加对 .distinct 的调用
Manager.all.joins(:sites).distinct.merge(Site.where(site_token: "..."))