【问题标题】:PG::UndefinedTable: ERROR: relation «productsrules» does not existPG::UndefinedTable: 错误: 关系 «productsrules» 不存在
【发布时间】:2013-12-04 13:21:19
【问题描述】:

我的一个 PG DB 表遇到了这个问题。我有一个表,其名称是“hproducts_rules”。这应该与“hproducts_matchs”表具有“belongs_to”关系。

这是我的表格架构:

hproducts_match

has_many :productsrule
default_scope order: 'id'
attr_accessible :productsrule_attributes, :product_id, :company_id, :product_key, :description, :condition
accepts_nested_attributes_for :productsrule, :reject_if => :all_blank, :allow_destroy => true
self.table_name = "hproducts_matchs"

hproducts_rule

belongs_to :productsmatch
default_scope order: 'id'
attr_accessible :productsmatch_id, :company_id, :product_key, :origen_comp, :line, :connector, :char_start, :char_end, :modeprize_id, code_opc, :ochar_start, :onchar_end self.table_name = "hproducts_rules"

当我尝试在“products_match”表单中添加部分内容时,我收到以下错误:

PG::UndefinedTable: ERROR: relation «productsrules» does not exists
LINE 5:              WHERE a.attrelid = '"productsrules"'::regclas...
                                        ^
:             SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                     pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
              FROM pg_attribute a LEFT JOIN pg_attrdef d
                ON a.attrelid = d.adrelid AND a.attnum = d.adnum
             WHERE a.attrelid = '"productsrules"'::regclass
               AND a.attnum > 0 AND NOT a.attisdropped
             ORDER BY a.attnum

我最初以为是因为我的表名是“hproducts_match”,而我的“products_rules”表上的参考字段是“productsmatch_id”,所以我将名称更改为“hproductsmatch_id”并得到了相同的结果。然后我将整个表名更改为“products_rules”而不是“hproducts_rules”,并且仍然相同。我什至在表和模型上加了一个foreign_key约束,还是一样。

我不确定该关系是否应该命名为“hproductsrules”或“productsrules”,所以也许这就是问题所在。我在哪里可以改变它?

我做了一些研究,其中大部分与迁移有关。我没有在我的数据库开发中使用迁移,我手动添加了表,就像我对每个表所做的那样。其他是关于 rspec 的,超出了我的范围。

有人知道为什么会这样吗?这仅在我使用表单中的部分时才会显示。

提前致谢。

编辑以显示我的答案

好的,由于某种明显的原因,我的应用程序假设我的表名是“productsrules”而不是“hproducts_rules”,所以我所做的就是将“self.table_name”行更改为模型的顶部,然后一切正常.

不确定这是否是这个问题的正确答案,但它帮助我解决了这个问题。

我将我的模型恢复到原始状态(我在这个问题开始时有一个)唯一的区别如下:

class Productsrule < ActiveRecord::Base
  self.table_name = "hproducts_rules"
  belongs_to :productsmatch
  default_scope order: 'id'
  attr_accessible :productsmatch_id, :company_id, :product_key, :origen_comp, :line,     :connector, :char_start, :char_end, :modeprize_id, code_opc, :ochar_start, :onchar_end
end

如您所见,self.table_name 行位于模型的开头。

感谢所有回复的人:)

【问题讨论】:

  • 您自己创建了表,并且您正在重命名东西,那么为什么不使用 rails 默认命名呢?它会让你的生活更轻松,而且命名约定是明智和好的。
  • 好吧,不一定是创建表的我,而是使用数据库的团队。但是,是的,你的建议很有道理,所以我以后会让他们知道。

标签: ruby-on-rails ruby activerecord rails-activerecord rails-postgresql


【解决方案1】:

当您不遵循 Rails 关联命名约定时,您必须明确指定外键和类名。类似于您明确设置表名的方式

hproducts_match

has_many :products_rules, :foreign_key => "productsmatch_id", :class_name => "HproductsRule"
default_scope order: 'id'
attr_accessible :productsrule_attributes, :product_id, :company_id, :product_key, :description, :condition
accepts_nested_attributes_for :productsrule, :reject_if => :all_blank, :allow_destroy => true
self.table_name = "hproducts_matchs"

hproducts_rule

belongs_to :products_match, :foreign_key => "productsmatch_id", :class_name => "HproductsMatch"
default_scope order: 'id'
attr_accessible :productsmatch_id, :company_id, :product_key, :origen_comp, :line, :connector, :char_start, :char_end, :modeprize_id, code_opc, :ochar_start, :onchar_end self.table_name = "hproducts_rules"

【讨论】:

  • 感谢 Vimsha,但现在我收到以下错误:{uninitialized constant Productsmatch::HproductsRules} 还有一个问题,是否可以将“productsmatch_id”作为 products_match 模型中的外键,即使这样那里不存在字段?
【解决方案2】:

如果你像这样编写关系,rails 将尝试根据关系名称派生类名和表名。

所以如果你写

has_many :productsrule

你写单数吗?这很奇怪,nr 1。但是 rails 会查找表 productsrules 和模型 Productsrule

如果你写:

has_many :hproducts_rules

它将查找模型HproductsRule 和表hproducts_rules。这似乎是你想要的。现在对于引用键,它将查找格式为 &lt;model-name&gt;_id 的外键,因此在您的情况下为 hproducts_match_id,并且该字段也不存在。

所以如果你想保持目前的情况,你可以这样写:

class HproductsMatch

  has_many :hproducts_rules, :foreign_key => 'productsmatch_id`

  default_scope order: 'id'
  attr_accessible :hproducts_rule_attributes, :product_id, :company_id, :product_key, :description, :condition
  accepts_nested_attributes_for :hproduct_rules, :reject_if => :all_blank, :allow_destroy => true
  self.table_name = "hproducts_matchs" 
end


class HproductsRule

  belongs_to :hproducts_match, :foreign_key => 'productsmatch_id'
  default_scope order: 'id'
  attr_accessible :productsmatch_id, :company_id, :product_key, :origen_comp, :line, :connector,
end

但既然您似乎可以完全控制您的数据库模型,为什么不写:

class ProductsMatch
  has_many :products_rules
  accepts_nested_attributes_for :products_rules
end

class ProductsRule
  belongs_to :products_match
end

在这种情况下,您的表 products_rules 带有外键 products_match_id 和表 products_matches

【讨论】:

  • 我尝试了你的第一个建议,以保持目前的情况,但在改变一切之后我又回到了“关系不存在”。我会尝试你的第二个建议,会让你知道结果如何。无论如何,谢谢nathanvda! :)
猜你喜欢
  • 2016-03-18
  • 1970-01-01
  • 2020-05-08
  • 2021-03-03
  • 1970-01-01
  • 2013-10-06
  • 2021-02-05
  • 2017-11-16
  • 1970-01-01
相关资源
最近更新 更多