Ruby on rails 解构Rails.joins&。方法在哪里
我有两种型号-Ruby on rails 解构Rails.joins&。方法在哪里,ruby-on-rails,ruby-on-rails-3,arel,Ruby On Rails,Ruby On Rails 3,Arel,我有两种型号-Banner和BannerType 他们的模式如下所示: Banner.joins(:banner_type).where("banner_types.name = ?", 'Featured') 横幅 # Table name: banners # # id :integer not null, primary key # name :string(255) # image :string(2
Banner
和BannerType
他们的模式如下所示:
Banner.joins(:banner_type).where("banner_types.name = ?", 'Featured')
横幅
# 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\u类型
并且Banner类型有很多:Banner
我在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">]
我知道我也可以通过banner\u type\u id=>1进行查询,但这与这个特定问题密切相关
如果我们打破这一说法,有几件事让我有点困惑
Banner.join(:Banner\u type)
-将为#
生成NoMethodError:undefined方法“join”
当这是SQL方法名称时,为什么没有Rails方法被称为join
Banner.join(:Banner\u type)
即当表名为Banner\u types
时使用单数Banner\u type
。我是否没有加入Banner&BannerType表(Rails惯例将其表示为复数)。如果我尝试Banner.joins(:Banner\u types)
这就是我得到的错误:
Banner.join(:Banner\u类型)
ActiveRecord::ConfigurationError:未找到名为“banner\u types”的关联;也许你拼错了?
where
子句需要banner\u类型
而不是banner\u类型
(即复数版本-即表名而非联接
方法中使用的符号?如果在两个位置使用表名或在两个位置使用符号名,似乎会更直观。如果至少出于一致性目的横幅,那就太好了。按横幅查找\u键入\u名称(“特色”)
#2 为什么我要使用Banner.joins(:Banner\u type)即当表名为Banner\u type时使用单数Banner\u type。我是否没有加入Banner和BannerType表(Rails约定表示为复数)。如果我尝试Banner.joins(:Banner\u type)这是我得到的错误: Banner.joins(:Banner\u types)ActiveRecord::ConfigurationError:找不到名为“Banner\u types”的关联;可能是您拼错了 在
.joins(:banner\u type)
中,:banner\u type
是您要加入的关系,而不是表。您有
has_one :banner_type
这就是Rails连接的原因。这就是Rails在将符号传递给.joins
时的工作方式,也是为什么在传递与模型的任何现有关联不匹配的符号时,错误会引用关联
这也是为什么您能够使用嵌套关联的符号来连接的多个层次的原因,如下所述
此外,还可以将字符串传递给。joins
Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')
注意,在最后一个示例中,当字符串传递给联接时,将使用表名地址,而不是关联名;这有助于回答#3
#3
为什么where子句需要banner_类型而不是banner_类型(即复数版本-即表名而不是JOIN方法中使用的符号)?如果在两个位置都使用表名或在两个位置都使用符号名,似乎会更直观。如果至少出于一致性目的
经过一点字符串插值后,传递给方法的字符串(类似于连接
)或多或少地直接传递到最终的SQL查询中(一路上会有一点ARel操作)。名称
是一个模棱两可的列(您的横幅
和横幅类型
表都有一个名称
列),因此通过其完整路径[表名].[列名]
引用该表是必需的。例如,如果您在横幅类型
中有一些颜色
列(在横幅
中也不存在),无需在where
方法中将其用作“banner\u types.color=?”
;“color=?”
就可以了
注意,就像在#2中一样,您可以将符号传递给where
方法,用于JOIN
'd表
Banner.joins(:banner_type).where(banner_type: [name: 'Featured'])
#4
为什么我不能通过关联进行动态查找?也就是说,如果我可以使用Banner.find_by_Banner_type_name(“特色”)
你不能做这样的查找,因为它在ARel中不受支持,它真的很简单(在我看来,像find_by_banner\u type\u name这样的方法名相当混乱)。Wow…感谢这个全面的解决方案-但我只想指出一个其他人已经删除的解决方案:BannerType.find_by_name(“特色”).banner
。这会满足我的最后一个问题,虽然有点倒退。我确实明白你的观点…这可能会有点混乱。另外…re:#2,我没有明确的有一个:banner\u type
。你是说因为banner属于:banner\u type
?所以实际上是有一个关系吗执行查询(连接)即使没有关联的工作也定义了一个吗?我从来没有尝试过。我也很好奇为什么你没有明确定义它。它现在工作得很好,我没有定义一个关联。我只是在BannerType
模型上定义了很多:banners
,而属于:b退火类型
在横幅上
model.Wor
Banner.joins(:banner_type).where(banner_type: [name: 'Featured'])