首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails内部连接期望字段"id“尚未存在

Rails内部连接期望字段"id“尚未存在
EN

Stack Overflow用户
提问于 2015-01-12 21:36:13
回答 2查看 745关注 0票数 1

简短版本:我需要使用自定义的内部连接来在一个表中找到id,其中两个字段在Rails的两个表中匹配,但是Rails内部连接对我不知道如何处理的关系做了假设。

长版本:我已经接管了一个Rails项目,它有一个非规范化的数据库。我将一些信息提取到一个新的表中,现在我需要遍历每个条目,并在原始表上放置一个外键,但是我很难找到正确的ActiveRecord查询来获取这些信息。

在这种情况下,集合属于存储库,存储库可能有许多集合。

该项目最初将所有集合和存储库存储在同一个表中,如果它是存储库,则为集合名称为NULL,如果是集合,则为存储库名称和集合名称。我创建了一个迁移,它使用了所有唯一的存储库名称,并将它们固定在存储库表中。现在,我需要做的是返回集合表,并根据string从匹配的存储库中添加id。

我在SQL中有一个查询,它提取正确的数据:

代码语言:javascript
复制
ActiveRecord::Base.connection.execute("SELECT r.id, r.repname FROM collections c, repositories r WHERE c.repname = r.repname")

但是,我在与该对象交互时遇到了困难(对于#Mysql2 2::Result.“获取诸如”未定义的方法'last‘“之类的错误),我更希望知道在Rails模型中一切都是正确的。

当我尝试这个时,我会得到一个错误:

代码语言:javascript
复制
Repository.joins(:collections).where("collections.repname = repositories.repname")
Repository Load (1.0ms)  SELECT `repositories`.* FROM `repositories` INNER JOIN `collections` 
ON `collections`.`repository_id` = `repositories`.`id` WHERE (collections.repname = repositories.repname)

Mysql2::Error: Unknown column 'collections.repository_id' in 'on clause': SELECT `repositories`.* FROM `repositories` INNER JOIN `collections` ON `collections`.`repository_id` = `repositories`.`id` WHERE (collections.repname = repositories.repname)
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'collections.repository_id' in 'on clause': SELECT `repositories`.* FROM `repositories` INNER JOIN `collections` ON `collections`.`repository_id` = `repositories`.`id` WHERE (collections.repname = repositories.repname)

我对Rails和SQL都很陌生,所以我认为我的问题实际上可能在于我如何建立模型。我正在使用数据库的现有命名conventions...maybe --我应该切换到Rails repository_id约定,而不是?

代码语言:javascript
复制
class Collection < ActiveRecord::Base
  has_many :archive_object_collections, :foreign_key => :collid, :primary_key => :collid
  has_many :archive_object, :through => :archive_object_collections
  belongs_to :repository, :foreign_key => "repid"
end

class Repository < ActiveRecord::Base
  has_many :collections
end

但是,我担心切换到repository_id不会解决这个问题,因为集合表上还没有任何类型的id。这就是为什么我需要运行这个查询,这样我就可以在集合表中作为外键找到并插入该信息。我已经尝试了集合类中没有foreign_key的内部联接查询,没有进行任何更改。

很抱歉这个冗长而复杂的问题。有人有什么建议吗?谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-12 22:59:26

我决定迭代集合和存储库表,并手动匹配它。这就是我最后所做的:

代码语言:javascript
复制
class AddForeignKeyToColl < ActiveRecord::Migration
  def up
    # Add a repid to the collections
    add_column :collections, :repository_id, :integer

    # Need to go through all of the repositories
    # and match their name against the repname of the collections
    # Then, if they match, add the repository id to the collection as repid
    repos = Repository.all
    colls = Collection.all
    repos.each do |repo|
      rname = repo.repname
      colls.each do |coll|
        if coll.repname == rname
          coll.update_attributes(:repository_id => repo.id)
        end
      end
    end
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

好像起作用了!

票数 0
EN

Stack Overflow用户

发布于 2015-01-12 21:58:25

我认为您应该在存储库模型中定义foreign_key。

代码语言:javascript
复制
class Repository < ActiveRecord::Base
  has_many :collections, :primay_key => 'somekey',  :foreign_key => 'repid'
end

然后,您可以运行一个简单的联接查询,根据查询获取一个结果。

代码语言:javascript
复制
Repository.select('repositories.*, collections.*').where("repositories.col1 = ? AND collections.col2 = ?", val1, val2)

否则,如果您想摆脱这些类型的键定义,那么最好开始使用rails约定。将外键定义为model_id。在这种情况下,您不必定义键名。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27911150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档