Rails - 如何在同一个表中创建对象之间的关系

时间:2017-05-19 14:08:28

标签: ruby-on-rails

我正在创建一个家庭相册应用程序。用户可以登录并创建一个" Family"宾语。创建族对象后,用户可以使用"成员填充家庭。"该应用程序允许您将一个成员创建为独立对象。创建第一个成员后,必须从现有成员的显示页面创建所有后续成员。创建它们时,正在创建的成员需要确定它与当前成员(显示页面)的关联方式。关系应该是父母'孩子'或者'兄弟姐妹。'

我有一些极端难以弄清楚如何做到这一点。解决方案需要同时做这些事情:

  1. 当一个新的'成员'创建后,两个对象都将记录新关系。
  2. 需要指定关系类型。它不能只是"会员"属于"成员。"它需要成为"成员" #1是"会员"#2的父母。
  3. 现在,这是成员表的架构:

    create_table "members", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.string   "birthplace"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "family_id"
    t.integer  "parent_id"
    t.integer  "child_id"
    t.integer  "sibling_id"
    end
    

    我还没有建立成员之间的has_many关系。创建新成员时,我只需将该新成员设为" parent_id"或者" child_id"或者" sibling_id"等于显示当前成员的id(同样,表单在成员显示页面中)

            <%= form_for [@family, @new] do |m| %> 
            <div class="form-group">
                <%= m.text_field :first_name, placeholder: "First Name", class: 'form-control' %>
            </div>
            <div class="form-group">
                <%= m.text_field :last_name, placeholder: "Last Name", class: 'form-control' %> 
            </div>
            <div class="form-group">
                <%= m.text_field :birthplace, placeholder: "Birthplace", class: 'form-control' %>
            </div>
            <div class="form-group">
                <label>Parent</label>
                <%= m.select :child_id, @members.collect { |m| [ m.full_name, m.id ] }, include_blank: true %>
            </div>
            <div class="form-group">
                <%= m.submit "Add", class:"btn btn-primary" %>
            </div>
            <% end %>
    

    这是一个非常愚蠢的方式来做它imo。理想情况下,我希望有一组单选按钮,表示&#34; Parent&#34;,&#34; Sibling&#34;和#34;孩子。&#34;用户必须单击其中一个按钮,但只能单击其中一个按钮。提交表单时,然后根据单击的单选按钮建立当前成员与新成员之间的关系。我目前的策略根本不更新当前成员。这种关系只能在一个方向上引用。这种方法还需要选择其他成员......这不是我想要的。

    我应该通过表使用has_many吗?救命!

1 个答案:

答案 0 :(得分:2)

你确实应该使用has_many_through,因为我认为你需要支持多种关系......父母可以拥有多个孩子,所以在父母中有一个child_id是不够的处理这种情况。

class Member < ApplicationRecord
  has_many :parent_links, class_name: 'ParentChildLink', foreign_key: :child_id
  has_many :parents, through: :parent_links, class_name: 'Member', foreign_key: :parent_id
  has_many :child_links, class_name: 'ParentChildLink',  foreign_key: :parent_id
  has_many :children, through: :parent_links, class_name: 'Member', foreign_key: :child_id
end

'parent_child_links'表有

class ParentChildLink < ApplicationRecord
  belongs_to :parent, class_name: 'Member', foreign_key: :parent_id
  belongs_to :child, class_name: 'Member', foreign_key: :child_id
end

现在通过铁轨的魔力,你可以做到......

tommy = Member.create(name: 'Tommy')
peter = Member.create(name: 'Peter')

peter.children << tommy