2

我试图让它工作,但它dosen't!Rails 3,嵌套的多级表单和has_many通过

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_users,并且具有user_id和event_id)。如果我在创建用户并提交后返回编辑表单,则user_type的值将在events_users中设置。 (我也试过没有formtastic) 有什么建议吗?谢谢!

---- ----编辑

我也试图让用户

<%= 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 %> 

前event_users但当时它只是抛出了我一个错误:

User(#2366531740) expected, got ActiveSupport::HashWithIndifferentAccess(#2164210940)

- 编辑 -

的link_to_association是formtastic茧方法(https://github.com/nathanvda/formtast IC-茧),但我试图做其他的方法,但结果相同

---编辑----

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 
+0

你能告诉我们的控制器创建行动? – Nerian 2011-01-14 18:29:25

+0

现在已添加! – jonepatr 2011-01-14 18:45:34

回答

2

说实话,我从来没有尝试过编辑或创建该方式has_many :through

花了一点时间,不得不修复formtastic_cocoon中的js以使其工作,所以这里是一个可行的解决方案。

您需要挑选EventUser型号,然后填写User型号(反之亦然)。

所以模型里面你写的:

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部分(这里来的魔法一点点):

.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部分(其实不一定是偏)

.nested-fields 
    = f.inputs do 
    = f.input :name 

这应该有效。 请注意,我必须更新formtastic_cocoon gem,所以你需要更新到0.0.2版本。

现在这将是容易地从一个简单下拉列表中选择的user_type,代替隐藏字段,例如使用

= f.input :user_type, :as => :select, :collection => ["Participator", "Organizer", "Sponsor"] 

的几点思考(现在我证明了它的工作原理):

  • 这将始终在运行中创建新用户,实际上消除了对EventUser的需要。你会允许从下拉菜单中选择现有的用户吗?
  • 我个人把它周围:让用户自己指定一个事件!
0

是否events_users模型没有一个ID列?由于有一个额外的字段(user_type),所以EventUser是一个模型,应该有一个ID。也许这就是为什么user_type没有在你的第一种情况下被设置。

+0

我一直在试图用增加一个ID,但它并没有任何区别:/ – jonepatr 2011-01-14 18:41:44