我有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 是我无法弄清楚如何设置它以便按我描述的方式工作。我可能需要另一种型号,但我无法弄明白。
我在这里做错了吗?
有人能帮助我吗?
答案 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: "..."))