ruby-on-rails – 解构Rails .joins&.where方法

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 解构Rails .joins&.where方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有两个模型 – 横幅和横幅类型.

他们的模式如下所示:

旗帜

# 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

BannerType

# Table name: banner_types
#
#  id         :integer          not null,primary key
#  name       :string(255)
#  created_at :datetime         not null
#  updated_at :datetime         not null

Banner belongs_to:banner_type和BannerType has_many: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">]

如果我想查询查找类型的所有横幅,我可以这样做:

Banner.joins(:banner_type).where("banner_types.name = ?",'Featured')

我知道我也可以通过banner_type_id => 1但这与这个特定的问题密切相关.

如果我们分解了这个声明,那么有一些与我有点混乱的事情.

> Banner.join(:banner_type) – 将生成NoMethodError:对于#< Class:0x007fb6882909f0>的undefined方法’join’为什么没有Rails方法叫做join,那就是sql方法的名字?
>为什么要做Banner.joins(:banner_type),即表名称是banner_types时的单数banner_type.我不加入Banner& BannerType表(Rails约定表示为复数).如果我尝试Banner.joins(:banner_types)这是我得到的错误

Banner.joins(:banner_types)
ActiveRecord :: ConfigurationError:未找到名为“banner_types”的关联;也许你拼错了吗?
>为什么where子句需要banner_types而不是banner_type(即多元化版本 – 即表名称,而不是连接方法中使用的符号?如果您在两个地方使用表名或使用在两个地方的符号名称,至少为了一致的目的.
>为什么我不能通过关联进行动态查找 – 也就是说,如果我能做到Banner.find_by_banner_type_name(“特色”)会很好吗?

很乐意听到你的想法.

谢谢.

解决方法

#1

Banner.join(:banner_type) – would generate NoMethodError: undefined method ‘join’ for # Why is there no Rails method called join when that is the sql method name?

当阅读简单的英语说“横幅连接横幅类型”与“横幅连接横幅类型”时,它会更加清晰.我不知道有更多的原因.

#2

Why do I do Banner.joins(:banner_type) i.e. the singular banner_type when the table name is banner_types. Am I not joining the Banner & BannerType tables (which Rails conventions denote as plural). If I try Banner.joins(:banner_types) this is the error that I get:

Banner.joins(:banner_types) ActiveRecord::ConfigurationError: Association named ‘banner_types’ was not found; perhaps you misspelled it?

在.joins(:banner_type)中::banner_type是您加入的关系,而不是表.你有

has_one :banner_type

所以这是Rails加入的.这就是当您将符号传递给.joins时,Rails如何工作,并且是当您传递符号不符合您的模型的任何现有关联时,错误是指关联的原因.

这也是为什么您可以使用嵌套关联的符号来深入使用JOIN的多层次,如in the Rails Guide所述

Category.joins(:posts => [{:comments => :guest},:tags])

也描述了in the Rails Guide,你也可以传递字符串到.

Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')

注意,在上一个例子中,当一个String被传递给join时,使用表名地址,而不是一个关联名;这有助于回答#3.

#3

Why does the where clause need banner_types and not banner_type (i.e. the pluralized version – i.e. the table name and not the symbol used in the joins method? It seems it would be more intuitive if you use the table names in both places or use the symbol names in both places. If at the very least,for consistency purposes.

经过一些字符串插值后,传递给where方法(类似于连接)的Strings或多或少地直接传递到最终的SQL查询中(AREL将会有一些操作). name是一个不明确的列(您的横幅和banner_types表都有一个名称列),所以通过它的完整路径[TABLE NAME]引用该表,需要[COLUMN NAME].例如,如果您在banner_types中有一些颜色列(横幅中也不存在),则不需要将其用作“banner_types.color =?”.在你的方法; “color =?”将工作正常.

注意,就像#2一样,您可以将符号传递给JOIN’d表的where方法.

Banner.joins(:banner_type).where(banner_type: [name: 'Featured'])

#4

Why can’t I do dynamic finding via associations – i.e. it would be nice if I could do Banner.find_by_banner_type_name(“Featured”)?

你不能这样做,因为它不支持AREL,这真的很简单(IMO,一个方法名称,如find_by_banner_type_name相当混乱).

猜你在找的Ruby相关文章