我有两个模型 - Banner
和BannerType
。
它们的架构如下:
Banner
# Table name: banners
#
# id :integer not null, primary key
# name :string(255)
# image :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# url :string(255)
# banner_type_id :integer
横幅类型
# Table name: banner_types
#
# id :integer not null, primary key
# name :string(255)
# created_at :datetime not null
# updated_at :datetime not null
Banner 属于 :banner_type
,而 BannerType 拥有多个 banners
我在 BannerType 中有两条记录,分别是:
BannerType.all
BannerType Load (0.3ms) SELECT "banner_types".* FROM "banner_types"
=> [#<BannerType id: 1, name: "Featured", created_at: "2012-12-17 04:35:24", updated_at: "2012-12-17 04:35:24">, #<BannerType id: 2, name: "Side", created_at: "2012-12-17 04:35:40", updated_at: "2012-12-17 04:35:40">]
如果我想查询所有类型为Featured
的横幅,可以尝试以下操作:
Banner.joins(:banner_type).where("banner_types.name = ?", 'Featured')
我知道我也可以查询banner_type_id => 1
,但这与此特定问题无关。
如果我们分解这个语句,有一些事情对我来说有点令人困惑。
Banner.join(:banner_type)
- 将生成NoMethodError: undefined method 'join' for #<Class:0x007fb6882909f0>
。为什么没有叫做join
的Rails方法,而这是SQL方法的名称?为什么要使用Singular
banner_type
,而不是表名banner_types
,比如Banner.joins(:banner_type)
。难道我不是在联接Banner和BannerType表(根据Rails约定表示为复数)吗?如果我尝试Banner.joins(:banner_types)
,会出现以下错误:Banner.joins(:banner_types) ActiveRecord::ConfigurationError: Association named 'banner_types' was not found; perhaps you misspelled it?
为什么
where
子句需要banner_types
而不是banner_type
(即复数形式-即表名而不是在joins
方法中使用的符号)?如果你在两个地方都使用表名或符号名,似乎更符合直觉。至少为了保持一致性。为什么我不能通过关联进行动态查找 - 即如果我可以使用
Banner.find_by_banner_type_name("Featured")
就好了?
希望听听你的想法。
谢谢。
BannerType.find_by_name('Featured').banners
。那会有点满足我的最后一个问题,尽管有点反向。我明白您的观点...那可能会有点令人困惑。 - marcamillionhas_one:banner_type
。您是说因为Banner belongs_to:banner_type
吗?这样实际上就是一个has_one
关系? - marcamillionhas_one
。我只在BannerType
模型上有has_many :banners
,并且在Banner
模型上有belongs_to :banner_type
。非常好用。 - marcamillionacts_as_shopping_cart
的经验吗?我需要一些关于这个问题的帮助 - http://stackoverflow.com/questions/13899686/using-acts-as-shopping-cart-how-do-i-implement-basic-quantity-editing - marcamillionjoin
是Array
上的一个方法;由于ActiveRecord::Relation
将它不知道的任何方法委托给懒加载的记录数组,如果你调用join
,就会触发数组方法。我猜joins
多了一个s
的原因是为了 1)避免混淆这两个方法 2)避免掩盖join
方法(别问我为什么,我不知道在哪种情况下会有用)3)让Relation
的接口感觉像是一个强化版的数组。 - m_x