2013-07-29 65 views
0

我试图建立一些关系,在我的Rails应用4,但我“遇到了一些麻烦,M I有四节课如下:红宝石4路的关系上轨

class Client < ActiveRecord::Base 
    has_many :checks 
    belongs_to :tier 
    has_many :months 
end 

class Check < ActiveRecord::Base 
    belongs_to :client 
    belongs_to :group, class_name: "Month" 
end 

class Tier < ActiveRecord::Base 
    has_many :clients 
    has_many :months 
end 

class Month < ActiveRecord::Base 
    has_many :clients 
    belongs_to :tier 
    has_many :checks, ->(month) { where deposit_date: month.start_date..month.end_date } 

    validates_uniqueness_of :group, scope: :tier_id 
end 

编辑:为了澄清,有三个'层'具有不同的月份结构,例如,第1层的'1月'将从第1层开始,第2层将从第3层开始,依此类推,其设计使得只有三层(即三个不同的月份结构),客户将只有一个层级,但通过这个层级需要多个月。对月份表格还有一个限制,以确保同一层级每月不超过1个条目。本质上是啊几个月和客户之间的abtm关系,但客户所在的层次决定了它回归的“团体”。

表格的设置方式使客户端和月份都有一个tier_id外键,支票有一个client_id外键和一个存款日期,一个月有一个tier_id和一个开始日期和结束日期。层级表或多或少是层级名称(层1,层2)的占位符,旨在将客户与他们的月份结合起来。我希望能够描述@ client.months,它会在表中找到匹配客户端层的所有月份。此外,我想做一些类似@ month.checks的事情,它会查找特定月份中为特定客户发布的所有支票。但我遇到了各种麻烦。

所以我想知道是否有办法让我当前的模式工作,如果我需要做出改变,或者如果我需要从头开始重新考虑整个事情!而且,更重要的是,如何到达那里....

编辑

的什么,我想从数据库返回的将采取以下形式在SQL的一个例子:

SELECT ch.* 
FROM clients cl 
JOIN tiers t ON cl.tier_id = t.id 
JOIN months m ON m.tier_id = t.id 
JOIN checks ch ON ch.client_id = clients.id 
WHERE clients.id = ? AND m.group = ? 

,或者更简单地说:

SELECT ch.* 
FROM clients cl 
JOIN months m ON m.tier_id = cl.tier_id 
JOIN checks ch ON ch.client_id = clients.id 
WHERE clients.id = ? AND m.group = ? 
+1

belongs_to应该总是单数......'belongs_to:tier' – SteveTurczyn

+0

感谢您的更正! – user1706938

+0

你能解释一下实际的层次吗? – depa

回答

0

删除tier_id虽然我并没有意识到它,我无意中在这里解决了一个小问题来回答我自己的问题:Rails relationships with foreign key between?

正如我在我的答案中所述,虽然这给出了m e我想要的东西,它不像'Rails Way',所以我很乐意提供有关如何改进解决方案的建议。

1

你的说明,它说明了层是连接客户和月的中间模型。

因此,您可以在层上引用客户端和月表,这意味着层表应该具有client_id和month_id。

如果您之前已经从客户表中删除tire_id,并且同样也从月表中删除tier_id。

,并与的has_many的模型关联:通过如下关系,这样你就可以访问client.months月。客户

class Client < ActiveRecord::Base 
    has_many :checks 
    has_many :tiers 
    has_many :months, through: :tiers 
end 

class Tier < ActiveRecord::Base 
    belongs_to :client 
    belongs_to :month 
end 

class Month < ActiveRecord::Base 
    has_many :tiers 
    has_many :clients, through: :tiers 
    has_many :checks, -> { where deposit_date: start_date..end_date } 
end 

class Check < ActiveRecord::Base 
    belongs_to :client 
    belongs_to :group, class_name: "Month" 
end 

注:
*添加CLIENT_ID和month_id到层表
*从月表中删除tier_id
*从客户表

+0

我可以理解这种方法,但是它会使分层表的大小和冗余度增加,并增加每个客户端和月份,而在我看来,它应该只有3行。我已经考虑完全绕过层级表,并用新的client_months表建立月与客户之间的关系 - 这会不会更有意义? – user1706938

+0

如果除了映射两个表格之外,还有其他所需的字段,那么您可以使用has_many,或者您可以简单地使用HABTM – user2801