0

我有委员会和会议对象。创建会议时,我想同时关联一个或多个委员会。CommitteeMeeting 是 Meeting 的嵌套属性。

几乎完全按照这里的解决方案,我得到以下参数:

--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
utf8: ✓
authenticity_token: us1hzugov7DDIpKNobOZJbuk14KsIsoz3uJRZEy2VRc=
meeting: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  date: '2001-01-03'
  room_id: '1'
  committee_meetings_attributes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
    '0': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
      committee_id: '1'
    '1': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
      committee_id: '2'
commit: Create meeting
action: create
controller: meetings

Committee_meeting_attributes 被正确嵌套,但在一个数组中,这似乎是导致错误的原因。Rails 期待一个哈希值。我用作参考的解决方案在参数中获取哈希值。

    {"user"=>{"password_confirmation"=>"[FILTERED]", 
"roles_attributes"=>{"id"=>"2"}, ...

这个问题中,开发人员在他的参数中遇到了类似的错误,但他的问题是无法在父模型中访问嵌套属性。我确实可以在模型中访问嵌套属性。

这是视图:

<% provide(:title, 'Create site') %>
<h1>Create meeting</h1>

<div class="row"> 
  <div class="span6 offset3">

    <%= form_for(@meeting) do |f| %>
    <%= render :partial => 'shared/error_messages', 
                           :locals => {:object => @meeting} %>

      <%= f.label :date %>
      <%= f.text_field :date %>

      <% @rooms.each do |room| %>
        <%= f.radio_button :room_id, room.id %> <%= room.name %><br />
      <% end %>

        <%= f.fields_for :committee_meetings do |builder| %>
          <% committee = Committee.find(builder.object.committee_id) %>
          <li><%= builder.check_box :committee_id, { :checked => false },
                        builder.object.committee_id %>
          <%= builder.label :committee_id, "#{committee.name}" %>
          </li>
        <% end %>

      <%= f.submit "Create meeting", class: "btn btn-large btn-primary" %>
    <% end %>
  </div>
</div>

这是会议控制器:

class MeetingsController < ApplicationController
 def create
    @rooms = Room.all
    @committees = Committee.all
    @meeting = Meeting.new(params[:meeting])
    @meeting.creator_id = current_user.id
    @meeting.updater_id = current_user.id

  if @meeting.save
    flash[:success] = "You have succesfully created a meeting on #{@meeting.date}
                       in #{@meeting.room.site.name}, #{@meeting.room.name}!"
    redirect_to root_url 
  else
    render 'new'
  end
end

  def new
    @rooms = Room.all
    @meeting = Meeting.new
    @committees = Committee.all
  end 

这是模型:

class Meeting < ActiveRecord::Base
attr_accessible :creator_id, :date, :room_id, :updater_id, :committee_meetings_attributes

  has_many :committee_meetings
  accepts_nested_attributes_for :committee_meetings, :allow_destroy => true

  has_many :committees, through: :committee_meetings

  belongs_to :room
  belongs_to :creator,     :class_name => 'User'
  belongs_to :updater,     :class_name => 'User'

end
4

1 回答 1

0

正如我在评论中所说,我可以向您展示我所做的事情,但它可能太聪明了一半,或者可能有一种更直接的方法来完成它,而我只是不知道。

对我来说,我希望我的所有委员会每次都以相同的顺序显示,所以我首先在我的new和控制器中预构建所有可能的关联以及andedit的失败案例。createupdate

我在这里有代码,它将确保所有可能的关联都存在,尊重已保存的关联并每次都以相同的方式对它们进行排序:

Rails:如何在构建之前添加或插入关联?

然后在我看来,我使用复选框来删除我不想保存的那些。

= f.fields_for :committee_meetings do |cm|
  = cm.check_box :_destroy, {:checked => cm.object.persisted?}, 0, 1
  = cm.label :_destroy, cm.object.committee.name
  = cm.hidden_field :committee_id, :value => f.object.committee.id

基本上,我已经颠倒了复选框的极性,所以如果它没有被选中,它就会发送:_destroy,或者如果它被选中则什么都不发送。

它对我有用,我相信你可以让它为你工作。恐怕我不能说你的代码为什么会失败,因为我不明白为什么它甚至部分工作。我宁愿只解决您的问题,但也许这种替代方法会有所帮助。

于 2013-01-24T19:39:00.237 回答