Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails模型具有多个外键_Ruby On Rails_Ruby_Model_Has Many - Fatal编程技术网

Ruby on rails Rails模型具有多个外键

Ruby on rails Rails模型具有多个外键,ruby-on-rails,ruby,model,has-many,Ruby On Rails,Ruby,Model,Has Many,对rails来说相对较新,并尝试用一个人模型来模拟一个非常简单的家庭“树”,该模型包含姓名、性别、父亲id和母亲id(两个父母)。下面是我想做的,但显然我不能重复:a中的子项有很多(第一个被覆盖) class-Person“个人” 属于:母亲,:class\u name=>“个人” 有很多:孩子,:class\u name=>'Person',:foreign\u key=>'mother\u id' 有很多:孩子,:class\u name=>'Person',:foreign\u key=>

对rails来说相对较新,并尝试用一个人模型来模拟一个非常简单的家庭“树”,该模型包含姓名、性别、父亲id和母亲id(两个父母)。下面是我想做的,但显然我不能重复:a中的子项有很多(第一个被覆盖)

class-Person“个人”
属于:母亲,:class\u name=>“个人”
有很多:孩子,:class\u name=>'Person',:foreign\u key=>'mother\u id'
有很多:孩子,:class\u name=>'Person',:foreign\u key=>'father\u id'
结束
有没有一种简单的方法可以使用带有两个外键的has_many,或者根据对象的性别更改外键?还是有其他更好的方法


谢谢

我相信你可以用has\u one实现你想要的关系

class Person < ActiveRecord::Base
  has_one :father, :class_name => 'Person', :foreign_key => 'father_id'
  has_one :mother, :class_name => 'Person', :foreign_key => 'mother_id'
  has_many :children, :class_name => 'Person'
end
class-Person'Person',:foreign\u key=>'father\u id'
有一个:母亲,:class\u name=>'Person',:foreign\u key=>'mother\u id'
有很多:孩子,:class\u name=>“Person”
结束

我会在下班后确认并编辑此答案;)

在IRC上找到了一个似乎有效的简单答案(多亏了雷达):

class-Person“个人”
属于:母亲,:class\u name=>“个人”
有很多:父亲的孩子,:class\u name=>'Person',:foreign\u key=>'father\u id'
有很多:母亲的孩子,:class\u name=>'Person',:foreign\u key=>'mother\u id'
def儿童
母亲的子女+父亲的子女
结束
结束

在人物模型上使用命名范围 这样做:

class-Person[“父亲id=?或母亲id=?”,pid,pid]}
}
结束

我更喜欢在这个问题上使用作用域。像这样:

class Person < ActiveRecord::Base
  belongs_to :father, :class_name => 'Person'
  belongs_to :mother, :class_name => 'Person'
  has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
  has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'

  scope :children_for, lambda {|father_id, mother_id| where('father_id = ? AND mother_id = ?', father_id, mother_id) }
end
要改进的答案,您可以通过定义
Person\children
来实现ActiveRecord关系,如:

def children
   children_of_mother.merge(children_of_father)
end

有关更多详细信息,请参见

这不是一般问题的解决方案(“has_many with multiple foreign key”),但是,考虑到一个人可以是母亲也可以是父亲,但不能同时是母亲和父亲,我会添加一个
性别
列,并使用

  has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
  has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'
  def children
    gender == "male" ? children_of_father : children_of_mother
  end

我正在寻找相同的功能,如果您不想返回数组,而是返回
ActiveRecord::AssociationRelation
,则可以使用
“个人”
有很多:父亲的孩子,:class\u name=>'Person',:foreign\u key=>'father\u id'
有很多:母亲的孩子,:class\u name=>'Person',:foreign\u key=>'mother\u id'
def儿童
母亲的孩子们我的回答只为你们

至于你的代码,这里是我的修改

class Person < ActiveRecord::Base
  belongs_to :father, :class_name => 'Person'
  belongs_to :mother, :class_name => 'Person'
  has_many :children, ->(person) { unscope(where: :person_id).where("father_id = ? OR mother_id = ?", person.id, person.id) }, class_name: 'Person'
end
class-Person“个人”
属于:母亲,:class\u name=>“个人”
有很多:孩子,->(person){unscope(where::person_id)。where(“父_id=?或母_id=?”,person.id,person.id)},类名:'person'
结束

那么有什么问题吗?

如果有任何默认范围,特别是那些可能影响结果顺序的范围,此解决方案将无法工作,因为结果的顺序将不符合预期。您可以通过定义#子对象(如我在下面的回答中所做的)来获得
ActiveRecord:Relation
,这不会触发两个SQL查询吗?警告:在Rails 4.2(可能还有之前的所有版本)中,调用
children
会触发两个SQL请求(一个用于
children\u(父亲的)
,一个用于
children\u(母亲的)
)。对于大数据集,这将是无效的@stefvhuynh,谢谢你提出这一点。对于Rails 3,作用域链接,ActiveRecord::Relation,以及最终的
有很多
:你正在寻找“复合键”:这对我不起作用。。。看起来不错,但我得到了
has\u many
关系的预期erorr:“表
people
中没有名为
person\u id
的列。警告:正如您在回答中所述,关系与
合并。这在本例中不起作用,因为这意味着您只选择将
母亲id
和(而不是)父亲id设置为目标id的人。我不是医生,但这种情况不应该经常发生:)。merge在我需要的情况下发挥了作用。非常感谢。这太棒了!关于StackOverflow的问题有几个不正确的答案,但是这个方法非常有效。快速更正:您拼错了
母亲id
@kallesamuelson谢谢您的支持!喜欢你的评论!电铲操作员(
Person.children_for father_id, mother_id
def children
   children_of_mother.merge(children_of_father)
end
  has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
  has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'
  def children
    gender == "male" ? children_of_father : children_of_mother
  end
class Person < ActiveRecord::Base
  belongs_to :father, :class_name => 'Person'
  belongs_to :mother, :class_name => 'Person'

  has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
  has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'

  def children
     children_of_mother << children_of_father
  end
end
class Person < ActiveRecord::Base
  belongs_to :father, :class_name => 'Person'
  belongs_to :mother, :class_name => 'Person'
  has_many :children, ->(person) { unscope(where: :person_id).where("father_id = ? OR mother_id = ?", person.id, person.id) }, class_name: 'Person'
end