mar*_*ion 12 ruby-on-rails arel ruby-on-rails-3
我有两个型号 - Banner和BannerType.
他们的架构如下所示:
旗帜
# 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
Run Code Online (Sandbox Code Playgroud)
BannerType
# Table name: banner_types
#
# id :integer not null, primary key
# name :string(255)
# created_at :datetime not null
# updated_at :datetime not null
Run Code Online (Sandbox Code Playgroud)
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">]
Run Code Online (Sandbox Code Playgroud)
如果我想查询以查找所有类型的横幅,Featured我可以执行以下操作:
Banner.joins(:banner_type).where("banner_types.name = ?", 'Featured')
Run Code Online (Sandbox Code Playgroud)
我知道我也可以查询,banner_type_id => 1但这与这个特定问题密切相关.
如果我们打破这种说法,有一些事情对我来说有点混乱.
Banner.join(:banner_type)- 会生成NoMethodError: undefined method 'join' for #<Class:0x007fb6882909f0>为什么join在SQL方法名称时没有调用Rails方法?为什么我这样做,Banner.joins(:banner_type)即banner_type表名是奇异的banner_types.我没有加入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")吗?
很想听听你的想法.
谢谢.
Banner.join(:banner_type) - 将生成NoMethodError:未定义的方法'join'为#为什么没有Rails方法称为连接,这是SQL方法名称?
当以简单的英语阅读"Banner加入横幅类型"与"横幅加入横幅类型"时,它更清晰.我不确定是否有更多理由.
为什么我做Banner.joins(:banner_type),即表名为banner_types时的单数banner_type.我没有加入Banner和BannerType表(Rails约定表示为复数).如果我尝试Banner.joins(:banner_types),这是我得到的错误:
Banner.joins(:banner_types)ActiveRecord :: ConfigurationError:找不到名为'banner_types'的关联; 也许你拼错了吗?
在.joins(:banner_type),:banner_type你正在加入的关系,而不是表格.你有
has_one :banner_type
Run Code Online (Sandbox Code Playgroud)
这就是Rails加入的内容.这就是当您将符号传递给Rails时Rails的工作原理,这就是当您传递符号与.joins模型的任何现有关联不匹配时错误引用关联的原因.
这也是为什么你能够JOIN使用嵌套关联的符号深入多层次的原因,如Rails指南中所述
Category.joins(:posts => [{:comments => :guest}, :tags])
Run Code Online (Sandbox Code Playgroud)
也可以在Rails指南中进行描述,也可以将字符串传递给.joins它.
Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')
Run Code Online (Sandbox Code Playgroud)
请注意,在最后一个示例中,当传递String时joins,使用表名 addresses,而不是关联名; 这有助于回答#3.
为什么where子句需要banner_types而不是banner_type(即复数版本 - 即表名而不是连接方法中使用的符号?如果你在两个地方使用表名或使用符号,它会更直观两个地方的名称.至少,为了一致性目的.
经过一些字符串插值后,传递给where方法的字符串(类似于joins)或多或少地直接传递到最终的SQL查询中(ARel会在此过程中进行一些操作).name是一个模糊的列(你banners和banner_types表都有一name列),所以需要通过它的完整路径[TABLE NAME].[COLUMN NAME]来引用表.例如,如果您有一些color列banner_types (也不存在banners),则不需要像"banner_types.color = ?"在您的where方法中那样使用它; "color = ?"会工作得很好.
注意,就像在#2中一样,您可以将符号传递where给JOIN'd表的方法.
Banner.joins(:banner_type).where(banner_type: [name: 'Featured'])
Run Code Online (Sandbox Code Playgroud)
为什么我不能通过关联进行动态查找 - 即如果我能做Banner.find_by_banner_type_name("精选")会很好吗?
你不能做那样的发现,因为它在ARel中不受支持,它就是那么简单(IMO,一个方法名称,比如find_by_banner_type_name令人困惑).
| 归档时间: |
|
| 查看次数: |
12444 次 |
| 最近记录: |