mind.blank
mind.blank

Reputation: 4880

Saving array through form not working correctly (using checkboxes and simple_form)

I'm trying to create an Email record, which can be saved as different types. For example an email that will be sent to all users, or one that will be sent to certain writers only.

Every option works except from the writers one, in which I'm trying to use checkboxes to save an id array, rather than retrieving the id array from the database.

class Email < ActiveRecord::Base
  validates_presence_of :subject, :body
  serialize :user_ids
  after_create :set_user_ids

  ...

  private

  def set_user_ids
    if mass_email?
      array = User.pluck(:id)
    elsif user_email?
      ...
    end
    self.user_ids ||= array
    self.max_mailings = user_ids.size
    save!
  end
end

The form (using simple_form):

<%= simple_form_for [:admin, @email] do |f| %>
  <% if writers?(params[:email_type]) %>
    <%= f.input :sent_to, as: :hidden, input_html: { value: "Writers" } %>
    <%= f.input :user_ids, collection: Writer.all.collect{ |w| [w.name, w.id] }, as: :check_boxes, label: false %>
    <br>
  <% end %>

  ...
<% end %>

The html:

<form accept-charset="UTF-8" action="/admin/emails" class="simple_form new_email" id="new_email" method="post" novalidate="novalidate">
  ...
  <div class="control-group check_boxes optional email_user_ids">
    <div class="controls">
      <label class="checkbox">
        <input class="check_boxes optional" id="email_user_ids_1" name="email[user_ids][]" type="checkbox" value="1" />
        John Smith
      </label>
      <label class="checkbox">
        <input class="check_boxes optional" id="email_user_ids_2" name="email[user_ids][]" type="checkbox" value="2" />
        Bob Brown
      </label>
      <input name="email[user_ids][]" type="hidden" value="" />
    </div>
  </div>

The usual new and create action:

class Admin::EmailsController < ApplicationController
  def new
    @email = Email.new
  end

  def create
    @email = Email.new(email_params)
    if @email.save
      flash[:success] = "Email saved successfully."
      redirect_to [:admin, @email]
    else
      render 'new'
    end
  end

  private

  def email_params
    params.require(:email).permit(:subject, :body, :email_type, :user_ids, :max_mailings, :sent_to)
  end
end

But when I try to submit the following error occurs, even though the user_ids param is present:

undefined method 'size' for nil:NilClass
Extracted source (around line #51):

49  end
50    self.user_ids ||= array
51    self.max_mailings = user_ids.size
52    save!
53  end

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"cVyUQY7Faqr6JpkdGoPwLhe+Pv6ld/7vzXLvBg+tzsk=",
 "email"=>{"sent_to"=>"Writers",
 "user_ids"=>["1",
 "2",
 ""],
 "subject"=>"Email to writers",
 "body"=>"Email to writers",
 "email_type"=>"writers"},
 "commit"=>"Create Email"}

I can't figure out why user_ids isn't updated correctly.
Also I'm not sure why an extra email[users_id][] field is rendered as a hidden field.

Upvotes: 1

Views: 1854

Answers (1)

user2636211
user2636211

Reputation:

I believe your problem may lie with your email_params method. Check out how to permit an array with strong parameters. It looks like you may need to explicitly declare that user_ids will be an Array.

Upvotes: 4

Related Questions