Vinicius Martinson
Vinicius Martinson

Reputation: 95

Saving arrays in Rails 4.2.3

I am having some trouble saving arrays in Rails.

Rails version: 4.2.3 | Ruby version: 2.2.1 | DB: PostgreSQL

In my view, I have a collection of check boxes that shows the conferences that my member attended.

<%= f.fields_for :conferences_member do |conference| %>
<%= collection_check_boxes(:conferences_member, :conference_id, @all_conferences, :id, :name)%>
<% end %>

I put a break point (binding.pry) after the create action in my MembersController, and surprisingly, it shows the selected check boxes:

Processing by Database::MembersController#create as HTML
Parameters: {"utf8"=>"✓","authenticity_token"=>"XYZ==",
[...] "conferences_member"=>     {"conference_id"=>["3", "5", ""]}, [...]

Now, if I go to rails c, and type ConferencesMember.last to check what was saved, I get:

pry(main)> ConferencesMember.last
ConferencesMember Load (0.5ms)  SELECT  "conferences_members".* FROM 
"conferences_members"  ORDER BY "conferences_members"."id" DESC LIMIT 1

=> nil

These are my associations:

#=> member.rb

has_one :conferences_member
accepts_nested_attributes_for :conferences_member, allow_destroy: true, reject_if: :all_blank

#=> conferences_member.rb

serialize :conference_id, Array
belongs_to :member  

#=> members_controller.rb

params.require(:member).permit( [...]
:conference_member_attributes => [:id, :member_id, :conference_id => []],
[...])

I want to thank you in advance. I've tried almost everything here on StackOverflow, but I don't see my error.

Thank you again.

EDIT:

More of my MembersController:

def new
    @member = Member.new
    @member.build_conferences_member
end

def create
    @member = Member.new(member_params)
    binding.pry
end

The log doesn't show any error, it just shows that conferences were not saved at all.

Upvotes: 0

Views: 144

Answers (1)

eirikir
eirikir

Reputation: 3842

First, your field needs to be renamed to nest the :conference_id in :conferences_member_attributes (not in :conferences_member as you do now). Take advantage of the form object yielded by fields_for:

<%= f.fields_for :conferences_member do |conference| %>
  <%= conference.collection_check_boxes :conference_id, @all_conferences, :id, :name %>
<% end %>

You also need to actually save the record in the create action: Member.new builds the record but does not save it. Typically, the create action branches based on whether the record saved or did not (due to validations). So you might rewrite this method like so:

def create
  @member = Member.new(member_params)
  # when @member.save returns true, it saved to the db successfully
  if @member.save
    redirect_to members_path, notice: "Member #{@member.id} saved!"
  # otherwise, it didn't save because of a validation error, so we render the error
  # to the user and give them a chance to fix it
  else
    flash[:error] = "Member didn't save: #{@member.errors.full_messages.to_sentence}"
    render :new
  end
end

Lastly, to make sure your data gets through your strong parameters, check your logs for any messages that parameters were filtered out. The messages look like:

Unpermitted parameters: your_favorite_attribute

Upvotes: 1

Related Questions