Rails Model has_many with multiple foreign_keys

前端 未结 8 1044
说谎
说谎 2020-11-28 06:04

Relatively new to rails and trying to model a very simple family \"tree\" with a single Person model that has a name, gender, father_id and mother_id (2 parents). Below is b

相关标签:
8条回答
  • 2020-11-28 06:09

    To improve on Kenzie's answer, you can achieve an ActiveRecord Relation by defining Person#children like:

    def children
       children_of_mother.merge(children_of_father)
    end
    

    see this answer for more details

    0 讨论(0)
  • 2020-11-28 06:12

    Found a simple answer on IRC that seems to work (thanks to Radar):

    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
    
    0 讨论(0)
  • 2020-11-28 06:12

    Not a solution to the general question as stated ("has_many with multiple foreign keys"), but, given a person can either be a mother or a father, but not both, I would add a gender column and go with

      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
    
    0 讨论(0)
  • 2020-11-28 06:13

    I was looking for the same feature, if you don't want to return an array but a ActiveRecord::AssociationRelation, you can use << instead of +. (See the ActiveRecord documentation)

    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
    
    0 讨论(0)
  • 2020-11-28 06:14

    Used named_scopes over the Person model do this:

    class Person < ActiveRecord::Base
    
        def children
          Person.with_parent(id)
        end
    
        named_scope :with_parent, lambda{ |pid| 
    
           { :conditions=>["father_id = ? or mother_id=?", pid, pid]}
        }
     end
    
    0 讨论(0)
  • 2020-11-28 06:15

    I believe you can achieve the relationships you want using :has_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
    

    I'll confirm and edit this answer after work ; )

    0 讨论(0)
提交回复
热议问题