我在使用 has_one :through
关联实现嵌套表单时遇到了一些麻烦。
模型
# model: member.rb
belongs_to :user
has_one :academic
# model: user.rb
has_one :member
has_one :academic, through: :member
accepts_nested_attributes_for :member, reject_if: :all_blank
accepts_nested_attributes_for :academic, reject_if: :all_blank
# model: academic.rb
belongs_to :member
belongs_to :user
Controller
# users_controller.rb
def new
@user = User.new
@user.build_member
@user.build_academic
end
我也尝试过:
@user.member.build_academic
查看
# new.html.erb
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |ff| %>
<%= ff.text_field :email %>
# member belongs to user so I can call a fields_for
<% ff.fields_for :member do |f| %>
<%= f.text_field :name %>
# this part is not shown. What is wrong with my association?
<% f.fields_for :academic do |a| %>
<%= a.text_field :major %>
<% end %>
<% end %>
<% end %>
我查看了 Rails 文档。第一个 fields_for
显示在页面 (:member
) 中,但第二个 (:academic
) 具有 has_one :通过
关联,页面中不显示。
任何帮助将不胜感激。谢谢。
最佳答案
通过
如果您想通过关系构建数据,则必须在构建关联数据时传递该数据:
#app/models/member.rb
class Member < ActiveRecord::Base
belongs_to :user
has_one :academic
accepts_nested_attributes_for :academic
end
#app/models/user.rb
class User < ActiveRecord::Base
has_one :member
has_one :academic, through: :member
accepts_nested_attributes_for :member
end
#app/models/academic.rb
class Academic < ActiveRecord::Base
belongs_to :member
belongs_to :user
end
这将允许您执行以下操作:
#app/controllers/members_controller.rb
class MembersController < ApplicationController
def new
@member = Member.new
@member.build_member.build_academic
end
def create
@member = Member.new member_params
@member.save
end
private
def member_params
params.require(:member).permit(:x, :y, :z, academic_attributes: [:some, :attributes, member_attributes:[...]])
end
end
这将允许以下操作:
#app/views/users/new.html.erb
<%= form_for @user do |f| %>
<%= f.fields_for :member do |m| %>
<%= f.text_field :name %>
...
<%= m.fields_for :academic do |a| %>
<% a.text_field :name %>
...
<% end %>
<% end %>
<%= f.submit %>
<% end %>
这可以从user
构建一个新的member
对象和一个新的academic
对象。虽然严格来说并不符合您的要求,但看起来它可以以某种形式使您受益。
协会
如果您想要执行您所要求的操作(IE build_member
和 build_academic
独占),您需要摆脱has_one :through
关系...
#app/models/user.rb
class User < ActiveRecord::Base
has_many :memberships
has_many :academics, through: :memberships
end
#app/models/membership.rb
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :academic
end
#app/models/academic.rb
class Academic < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
问题是您基本上是在尝试建立直接关联(成员
)的关系和间接关系(学术
) .
如果您想专门构建两者,您必须使它们与您的主模型直接关联。上述内容应该允许您执行以下操作:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new
@user.members.build.academics.build
end
end
与我的顶部示例非常相似,这将通过您的表单传递嵌套数据 - 如果您想完全独占它,请执行以下操作:
#app/models/user.rb
class User < ActiveRecord::Base
has_one :member
has_one :academic
has_and_belongs_to_many :academics
end
#app/models/member.rb
class Member < ActiveRecord::Base
belongs_to :user
end
#app/models/academic.rb
class Academic < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :users
end
这将允许以下操作:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new
@user.build_member
@user.build_academic
end
def create
@user = User.new user_params
@user.save
end
private
def user_params
params.require(:user).permit(:user, :params, member_attributes: [], academic_attributes:[])
end
end
关于ruby-on-rails - 带有 has_one 的嵌套表单 :through,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33326030/