Rails 3,嵌套的多层表单和has_many通过 [英] Rails 3, nested multi-level forms and has_many through

查看:87
本文介绍了Rails 3,嵌套的多层表单和has_many通过的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使其正常运行,但没有成功!

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆