开发者

Odd way of using nested forms (Rails)

I'm writing a (text) messaging app with Rails. I'm using nested_forms to allow you to send a message to multiple people.

In the controller, I instantiate a new Message object, then for each Member, build a Recipient object (child of Message). In the form, I display a checkbox next to each recipient. I want it so that the new Message object only has the recipients that have checks next to them. This is not working.

So by the time the form is rendered, Recipient objects are instantiated for all members. In other words, by default, a message gets sent to each member, unless specified not to. But I want to use the form to allow the user to specify who he wants the messages sent to

Here are my models:

class Message < ActiveRecord::Base
   has_many :recipients
   accepts_nested_attributes_for :recipients    
   #columns: body:string, from:string, from_member_id:integer
end

class Member < ActiveRecord::Base
   #columns phone:string, name:string
end

class Recipient < ActiveRecord::Base
  belongs_to :message
  belongs_to :member
  #开发者_开发知识库columns: member_id:integer, message_id:integer
end

messages_controller.rb:

def new
  @message = Message.new
  @members = Member.all
  @members.each do |member|
    @message.recipients << Recipient.new(:member_id => member.id)
  end
end

def create
   @message = Message.new(params[:message])
   redirect_to '/somewhere'
end
...

And here's my form for Message (app/views/message/new/html.erb)

<%= form_for(@message) do |f| %>
  <% if @message.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@message.errors.count, "error") %> prohibited this message from being saved:</h2>

      <ul>
      <% @message.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

    <%= f.fields_for :recipients do |builder| %>
        <div class="field">
            <input type="checkbox" value="<%= builder.object.member_id %>" name="recipients[id]" />
    /*WHAT GOES ^^^HERE^^^? */
            <%= builder.object.member.name %>
        </div>
    <% end %>


  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_field :body %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

The commented line in the form is where I'm having trouble. Also, it seems I might need to modify some code in MessagesController#create, but I'm not sure where to start.


First, instead of writing your checkbox HTML by hand, you should use the Rails helpers for this. It'll save you a lot of work, particularly in redisplaying the form upon a validation failure.

To do this, you'll need to create an attribute on your Recipient class:

class Recipient
  attr_accessor :selected
end

Then you can hook up that attribute to the checkbox:

<%= builder.check_box :selected %>

The next step is to make that attribute do something. You could try using the :reject_if option for accepts_nested_attributes_for. You could pass it a proc that returns true if the checkbox is not checked, e.g.:

accepts_nested_attributes_for :recipients, :reject_if => proc { |attributes| attributes['selected'] != '1' }

See these docs for details on :reject_if:

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜