【发布时间】: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"=>{"description"=>"Deliver System", "goal_status_id"=>"2", "goal_type_id"=>"1", "user_ids"=>["", "1", "2", "4"], "child_ids"=>["", "1", "2"]}, "commit"=>"Update Goal", "id"=>"1"- 我认为当它保存 child_ids 时,它不知道必须将 parent_id 设置为我正在编辑的 goal_id。
标签: ruby-on-rails ruby ruby-on-rails-4 many-to-many has-many-through