【问题标题】:How to save my many-to-many relationship?如何挽救我的多对多关系?
【发布时间】:2015-05-19 00:02:42
【问题描述】:

我正在尝试创建一个表单来保存相当复杂的关系。关系模型如下。

class Goal < ActiveRecord::Base
  belongs_to :goal_status
  belongs_to :goal_type

  has_many :users, through: :user_goals
  has_many :user_goals

  has_many :parent_goals, class_name: 'GoalDependency', foreign_key: :parent_id
  has_many :child_goals, class_name: 'GoalDependency', foreign_key: :child_id

  has_many :children, through: :child_goals
  has_many :parents, through: :parent_goals

  validates_presence_of :goal_status_id, :goal_type_id
end

class GoalDependency < ActiveRecord::Base
  belongs_to :parent, class_name: 'Goal', foreign_key: 'parent_id'
  belongs_to :child, class_name: 'Goal', foreign_key: 'child_id'
end

所以一个目标可以有很多父母,也可以有很多孩子,或者两者兼而有之。我曾尝试使用多选下拉菜单来保存这些关系并设置 child_ids/parent_ids,但这似乎不起作用,因为 goal_dependency 需要两个字段 - 即 child_id 和 parent_id。 Rails 只设置了一个。因此,如果我要保存 child_ids 列表,它会设置这些,但它不知道将 parent_id 设置为当前目标,反之亦然。

我尝试过使用accepts_nested_attributes,但我不确定如何将它与多选下拉菜单一起使用。

任何关于我如何解决这个问题的指导或指导将不胜感激。

我当前表单的示例。

.row
  .col-md-6
    = simple_form_for(@goal) do |f|
      - if @goal.errors.any?
        #error_explanation
          h2 = "#{pluralize(@goal.errors.count, 'error')} prohibited this goal from being saved:"

          ul
            -@goal.errors.full_messages.each do |message|
              li = message

      = f.input :description
      = f.input :goal_status_id, collection: @goal_statuses, value_method: :id, label_method: :name, as: :select
      = f.input :goal_type_id, collection: @goal_types, value_method: :id, label_method: :name, as: :select
      = f.input :user_ids, collection: @users, as: :select, label: 'Assigned To', input_html: { class: 'chosen-select', multiple: true }, selected: @goal.user_ids
      = f.input :child_ids, collection: @goals, as: :select, label: 'Children Goals', input_html: { class: 'chosen-select', multiple: true }, selected: @goal.child_ids, value_method: :id, label_method: :description

      br
      = f.submit

经过进一步调查,我想到了另一种方法来做到这一点,但我对此并不满意。我可以将依赖项的概念拆分为父依赖项和子依赖项,并将它们作为不同的模型。然后可以以不同的方式处理这种关系。有关子依赖项,请参见下面的代码。

class Goal < ActiveRecord::Base
  belongs_to :goal_status
  belongs_to :goal_type

  has_many :users, through: :user_goals
  has_many :user_goals

  has_many :child_goals, class_name: 'GoalChildDependency'
  has_many :children, through: :child_goals

  validates_presence_of :goal_status_id, :goal_type_id
end

class GoalChildDependency < ActiveRecord::Base
  belongs_to :goal
  belongs_to :child, class_name: 'Goal', foreign_key: :child_id
end

根据我的阅读,rails 无法处理复合键,而我的情况似乎是复合键有意义的情况。

无论如何,如果有人能弄清楚如何让我的初始代码工作,那就太好了。

【问题讨论】:

  • 您至少需要发布您当前的表单代码。
  • 您是否尝试过使用这样的关联字段? = f.association(:children, collection: Goal.all, include_blank: false, input_html: { class: 'chosen-select' })
  • 不,那行不通。我从表格中得到了相同的参数。 "goal"=&gt;{"description"=&gt;"Deliver System", "goal_status_id"=&gt;"2", "goal_type_id"=&gt;"1", "user_ids"=&gt;["", "1", "2", "4"], "child_ids"=&gt;["", "1", "2"]}, "commit"=&gt;"Update Goal", "id"=&gt;"1" - 我认为当它保存 child_ids 时,它不知道必须将 parent_id 设置为我正在编辑的 goal_id。

标签: ruby-on-rails ruby ruby-on-rails-4 many-to-many has-many-through


【解决方案1】:

也许使用带有自引用parent_id 列的单一目标模型会更容易。你可以在哪里做

has_many :child_goals, class_name: 'Goal', foreign_key: :parent_id

belongs_to :parent_goal, class_name: 'Goal'

此外,如果您仍然需要 ChildGoal 模型,您可以拥有一个单表继承模型,将列 type 添加到目标表并拥有 ChildGoal &lt; Goal 并遵循与上述类似的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2013-01-18
    相关资源
    最近更新 更多