1

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.

4
  • it think u had missed self before user_ids Commented Feb 2, 2014 at 13:51
  • params are not accessible inside model Commented Feb 2, 2014 at 13:54
  • In Rails you don't have to add the self. Doing self.user_ids and user_ids is exactly the same in this case. It's just convention to add self when assigning a value. Commented Feb 2, 2014 at 13:55
  • I'm not trying to access the params though. They should already be saved through the form. I'm using after_create to update other attributes based on what's saved (or not saved). Commented Feb 2, 2014 at 13:56

1 Answer 1

4
+50

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that worked! I'll give you the bounty when it lets me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.