Rails ActiveRecord has_many通过不工作

时间:2013-08-14 18:04:20

标签: ruby-on-rails postgresql activerecord foreign-keys schema

我有一个用户有孩子的rails应用程序。所以我有两个模型:用户和:孩子。

我曾经有一对多的关系(has_many / belongs_to),但我想把它打开到多对多的关系,我可以存储关于关系的变量。所以我把关系变成了" has_many通过"关系。我创建了一个名为:relationships的表。一个小警告:我希望用户的foreign_key为:parent_id。以下是我设置它们的方法:

架构:

create_table "relationships", :force => true do |t|
    t.integer  "child_id"
    t.integer  "parent_id"
    t.datetime "created_at"
.
.
.

create_table "users", :force => true do |t|
    t.string   "email",                                  :null => false
    t.datetime "created_at",                             :null => false
    t.datetime "updated_at",                             :null => false
    t.string   "first_name"
    t.string   "last_name"
.
.
.

create_table "children", :force => true do |t|
    t.string   "name",                :null => false
    t.integer  "parent_id",           :null => false
    t.datetime "created_at",          :null => false
.
.
.

班级定义:

user.rb:

has_many :relationships, foreign_key: "parent_id"
has_many :children, :through => :relationships, foreign_key: "parent_id"

child.rb:

has_many :relationships, foreign_key: "child_id"
has_many :parents, :through => :relationships

relationship.rb:

belongs_to :parent, class_name: "User", :foreign_key => :parent_id
belongs_to :child, class_name: "Child", :foreign_key => :child_id

现在,当我选择特定用户并尝试获取user.children时,我得到[]作为回应。如果我尝试添加新的孩子,它也不起作用。我可以定义父项和子项,但是当它尝试保存时,它无法将两者相关联。它没有看到父母,所以我得到错误:

* ActiveRecord :: StatementInvalid(PG ::错误:错误:列&#34中的空值; parent_id"违反非空约束*

如果我将类定义切换回一对多设置,它就可以很好地访问子节点。我不明白问题所在。任何帮助都将非常感激。

由于

2 个答案:

答案 0 :(得分:0)

你是如何建立这种关系的?当我按如下方式创建关系时,@user.children使用给定的示例为我工作:

@user.relationships.build(child_id: ...) 

答案 1 :(得分:-1)

如果要将子项创建为嵌套属性,则应允许子表parent_id中的

取空值。

更改

create_table "children", :force => true do |t|
  t.string   "name",                :null => false
  t.integer  "parent_id",           :null => false
  t.datetime "created_at",          :null => false
end

   create_table "children", :force => true do |t|
      t.string   "name",                :null => false
      t.integer  "parent_id"
      t.datetime "created_at",          :null => false
    end