【问题标题】:Rails 3, nested multi-level forms and has_many throughRails 3,嵌套多级表单和 has_many 通
【发布时间】:2011-01-12 17:15:21
【问题描述】:

我正在尝试让它工作,但它没有!

我有

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 中设置。 (我也试过没有formtastic) 有什么建议?谢谢!

----编辑----

我也尝试在用户之前拥有 event_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 %>

但它只会给我一个错误:

用户(#2366531740) 预期,得到 ActiveSupport::HashWithIndifferentAccess(#2164210940)

--编辑--

link_to_association 是一种 formtastic-cocoon 方法 (https://github.com/nathanvda/formtastic-cocoon) 但我尝试过其他方法但结果相同

---编辑----

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

【问题讨论】:

  • 你能告诉我们控制器创建动作吗?

标签: ruby-on-rails nested-forms has-many-through formtastic cocoon-gem


【解决方案1】:

说实话,我从未尝试过以这种方式编辑或创建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 的需求。您是否也允许从下拉列表中选择现有用户?
  • 我个人会扭转这种局面:让用户将自己分配给一个事件!

【讨论】:

  • 哇!我不敢相信你真的解决了这个问题!你是我的英雄!太感谢了!!主办方之所以添加所有参与者,是因为该事件是在实际事件之后添加的,以解决事件期间发生的经济相关问题。是的,我正在添加现有用户!再次感谢!!
  • 您知道如何将 user_type 添加到从多下拉列表中选择的用户(现有)吗?
  • _event_user_fields部分我现在自动创建一个新用户。而不是这样做,您可以使用两个链接:1 添加新用户,1 从下拉列表中添加现有用户。够清楚吗?
  • 你不会想看看我非常相似的问题吧? stackoverflow.com/questions/11199572/…
【解决方案2】:

events_users 模型没有 ID 列吗?因为有一个额外的字段(user_type),所以 EventUser 是一个模型,应该有一个 ID。也许这就是为什么在您的第一个案例中没有设置 user_type 的原因。

【讨论】:

  • 我一直在尝试添加一个 ID,但它没有任何区别:/
  • 奇怪的是它是在更新时设置的,而不是在创建时设置的!
猜你喜欢
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 2018-04-23
  • 1970-01-01
  • 2017-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多