Rails 3,嵌套的多层表单和has_many通过 [英] Rails 3, nested multi-level forms and has_many through
问题描述
我正在尝试使其正常运行,但没有成功!
I'm trying to get it to work but it dosen't!
我有
class User < ActiveRecord::Base
has_many :events, :through => :event_users
has_many :event_users
accepts_nested_attributes_for :event_users
end
class Event < ActiveRecord::Base
has_many :event_users
has_many :users, :through => :event_users
accepts_nested_attributes_for :users
end
class EventUser < ActiveRecord::Base
set_table_name :events_users
belongs_to :event
belongs_to :user
accepts_nested_attributes_for :events
accepts_nested_attributes_for :users
end
还有表格布局
event_users
user_id
event_id
user_type
events
id
name
users
id
name
这是我的表格
<%= semantic_form_for @event do |f| %>
<%= f.semantic_fields_for :users, f.object.users do |f1| %>
<%= f1.text_field :name, "Name" %>
<%= f1.semantic_fields_for :event_users do |f2| %>
<%= f2.hidden_field :user_type, :value => 'participating' %>
<% end %>
<% end %>
<%= link_to_add_association 'add task', f, :users %>
<% end %>
问题是,如果我以这种方式创建新用户,则不会设置user_type的值(但会创建一个用户以及具有user_id和event_id的event_users).如果我在创建用户后返回到编辑表单并提交,那么user_type的值将在events_users中设置. (我也尝试过没有形式主义) 有什么建议?谢谢!
The problem is that if I create a new user this way, it doesn't set the value of user_type (but it creates a user and a event_users with user_id and event_id). If I go back to the edit-form after the creation of a user and submit, then the value of user_type is set in events_users. (I have also tried without formtastic) Any suggestions? Thanks!
----编辑----
----edit----
我还尝试过将event_users放在用户之前
I have also tried to have the event_users before users
<%= semantic_form_for @event do |f| %>
<%= f.semantic_fields_for :event_users do |f1| %>
<%= f1.hidden_field :user_type, :value => 'participating' %>
<%= f1.semantic_fields_for :users do |f2| %>
<%= f2.text_field :name, "Name" %>
<% end %>
<% end %>
<%= link_to_add_association 'add task', f, :event_users %>
<% end %>
但这只会引发一个错误:
but then it only throws me an error:
预期用户(#2366531740)已获得 ActiveSupport :: HashWithIndifferentAccess(#2164210940)
User(#2366531740) expected, got ActiveSupport::HashWithIndifferentAccess(#2164210940)
-编辑-
link_to_association是一种形式上的茧方法(https://github.com/nathanvda/formtastic-cocoon),但是我尝试了其他方法,但是结果相同
the link_to_association is a formtastic-cocoon method (https://github.com/nathanvda/formtastic-cocoon) but I have tried to do other approaches but with the same result
-编辑----
def create
@event = Event.new(params[:event])
respond_to do |format|
if @event.save
format.html { redirect_to(@event, :notice => 'Event was successfully created.') }
format.xml { render :xml => @event, :status => :created, :location => @event }
else
format.html { render :action => "new" }
format.xml { render :xml => @event.errors, :status => :unprocessable_entity }
end
end
end
推荐答案
老实说,我从未尝试过以此方式编辑或创建has_many :through
.
To be honest, i have never tried to edit or create a has_many :through
in that way.
花了一些时间,不得不修复 formtastic_cocoon 内的js,这样它才能正常工作这是一个可行的解决方案.
It took a little while, and had to fix the js inside formtastic_cocoon to get it working, so here is a working solution.
您需要指定EventUser
模型,然后填充User
模型(反之亦然).
You need to specift the EventUser
model, and then fill the User
model (the other way round will never work).
因此,在模型内部编写:
So inside the models you write:
class Event < ActiveRecord::Base
has_many :event_users
has_many :users, :through => :event_users
accepts_nested_attributes_for :users, :reject_if => proc {|attributes| attributes[:name].blank? }, :allow_destroy => true
accepts_nested_attributes_for :event_users, :reject_if => proc {|attributes| attributes[:user_attributes][:name].blank? }, :allow_destroy => true
end
class EventUser < ActiveRecord::Base
belongs_to :user
belongs_to :event
accepts_nested_attributes_for :user
end
class User < ActiveRecord::Base
has_many :events, :through => :event_users
has_many :event_users
end
然后查看.从events/_form.html.haml
= semantic_form_for @event do |f|
- f.inputs do
= f.input :name
%h3 Users (with user-type)
#users_with_usertype
= f.semantic_fields_for :event_users do |event_user|
= render 'event_user_fields', :f => event_user
.links
= link_to_add_association 'add user with usertype', f, :event_users
.actions
= f.submit 'Save'
(我暂时忽略错误)
然后,您将需要指定部分_event_user_fields.html.haml
部分(这里有些神奇):
(i ignore errors for now)
Then, you will need to specify the partial _event_user_fields.html.haml
partial (here comes a little bit of magic) :
.nested-fields
= f.inputs do
= f.input :user_type, :as => :hidden, :value => 'participating'
- if f.object.new_record?
- f.object.build_user
= f.fields_for(:user, f.object.user, :child_index => "new_user") do |builder|
= render("user_fields", :f => builder, :dynamic => true)
并结束_user_fields
部分(实际上并不一定是部分)
and to end the _user_fields
partial (which does not really have to be a partial)
.nested-fields
= f.inputs do
= f.input :name
这应该有效. 请注意,我必须更新 formtastic_cocoon gem ,因此您需要更新至0.0.2版.
This should work. Do note that i had to update the formtastic_cocoon gem, so you will need to update to version 0.0.2.
现在,可以很容易地从一个简单的下拉列表中选择user_type
,而不是一个隐藏字段,例如使用
Now it would be easily possible to select the user_type
from a simple dropdown, instead of a hidden field, e.g. use
= f.input :user_type, :as => :select, :collection => ["Participator", "Organizer", "Sponsor"]
一些想法(现在我证明它可行):
Some thoughts (now i proved it works):
- 这将始终动态地创建新用户,实际上消除了对
EventUser
的需求.您是否也允许从下拉列表中选择现有用户? - 我个人想解决一下:让用户将自己分配给活动!
- this will always create new users on the fly, actually eliminating the need for the
EventUser
. Will you allow selecting existing users from a dropdown too? - personally i would turn it around: let users assign themselves to an event!
这篇关于Rails 3,嵌套的多层表单和has_many通过的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!