【问题标题】:has_one on a belongs_to in Rails?在 Rails 中的 belongs_to 上有 has_one?
【发布时间】:2009-05-07 18:39:26
【问题描述】:

我正在构建一个 Rails 站点,但在关联方面遇到了问题。基本上我有以下几点:

class Publication < ActiveRecord::Base
  belongs_to :category
  has_one    :site, :through => :category
  named_scope :on_site,        lambda {|s| {:include => [:site], :conditions => ['sites.slug != ?', 's']}}
end
class Category
  belongs_to :site
  has_many   :publications
end
class Site
  has_many :categories
  has_many :publications, :through => :categories, :foreign_key => 'category_id'
end

Publication.first.site 生成第一个出版物的站点,site.first.publications 也一样。

问题在于 on_site 命名范围,它会产生以下错误,类似于 Publication.on_site('s')

Mysql::Error: Unknown column 'categories.category_id' in 'on clause': SELECT 
`publications`.`id` AS t0_r0, `publications`.`shoot_id` AS t0_r1, 
`publications`.`category_id` AS t0_r2, `publications`.`title` AS t0_r3, 
`publications`.`slug` AS t0_r4, `publications`.`publish_on` AS t0_r5, 
`publications`.`created_at` AS t0_r6, `publications`.`updated_at` AS t0_r7, 
`publications`.`description` AS t0_r8, `publications`.`media_base_path` AS t0_r9, 
`sites`.`id` AS t1_r0, `sites`.`name` AS t1_r1, `sites`.`created_at` AS t1_r2, 
`sites`.`updated_at` AS t1_r3, `sites`.`slug` AS t1_r4, `sites`.`description` AS t1_r5, 
`sites`.`dhd_merch_id` AS t1_r6, `sites`.`members_area_url` AS t1_r7 FROM `publications`
 LEFT OUTER JOIN `categories` ON (`publications`.`id` = `categories`.`category_id`)  
 LEFT OUTER JOIN `sites` ON (`sites`.`id` = `categories`.`site_id`) WHERE (sites.slug != 's')

我需要那个连接是 Publications.category_id = categories.id,知道我哪里错了吗?

【问题讨论】:

    标签: ruby-on-rails activerecord associations


    【解决方案1】:

    嗯,这是您当前实现的一个问题:

    LEFT OUTER JOIN `categories` ON (`publications`.`id` = `categories`.`category_id`)
    

    那个 SQL sn-p 是由Site 中的这个关联定义创建的:

    has_many :publications, :through => :categories, :foreign_key => 'category_id'
    

    那里的foreign_key 不正确。 Rails 在categories 中查找名为category_id 的列,并希望该列的值与某个发布ID 匹配。但是没有可以设置的正确 foreign_key 选项,因为 categories 表看起来没有对 publications 表的引用 - 它是相反的方式。

    我不确定是否可以通过中间的has_many 关联使 ActiveRecord 的 has_many :through 关联工作。但我认为您可以使用嵌套关联功能来完成这项工作:

    class Publication < ActiveRecord::Base
      belongs_to :category
      #has_one    :site, :through => :category
      named_scope :on_site,        lambda {|s| {:include => { :category => :site }, :conditions =>  ['sites.slug != ?', s]}}
    end
    

    另一个问题是您将s 放在条件数组的引号中。它不应该用引号引起来。

    【讨论】:

    • 杰西,我会在星期一试一试,我很确定我在尝试加入之前尝试了所有这些东西,但是它没有用(我很确定你发布的是我的第一个实现,在我开始做其他各种事情之前)。至于引号中的 s,我认为这并不是问题的症结所在。如果您查看我粘贴的生成 SQL,则连接正在尝试将 publication.id 与 category.category_id 匹配。实际上它需要是publication.category_id和category.id。
    • 哦,是的,引用的s 是一个完全独立的问题。我只是想指出这一点。
    • 好吧,看起来你发布的代码没有修复它,我仍然需要手动进行连接。您的 named_scope 会产生相同的错误,它会尝试查找不存在的列 sites_publications_join.category_id
    • 您是否尝试从站点中删除 has_many :publications... 行?这可能会让事情变得混乱。
    【解决方案2】:

    好吧,如果有人感兴趣的话,我找到了一个使用:joins 范围选项的解决方案。但是,我仍然想知道是否可以不使用:joins

      named_scope :on_site,        lambda {|s| {:joins =>
       ['LEFT OUTER JOIN `categories` ON  (`publications`.`category_id` = `categories`.`id`) ',
       'LEFT OUTER JOIN `sites`      ON  (`sites`.`id` = `categories`.`site_id`)'],
       :conditions => ['sites.slug = ?', s]}}
    

    【讨论】:

    • 我希望你可以评论 Jesse 的回复,因为它似乎有效。
    猜你喜欢
    • 2014-05-05
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    相关资源
    最近更新 更多