Josiah Palmer
Josiah Palmer

Reputation: 151

Rails 4 many to many relationship

I have an app that has 2 models that need a many to many relationship. I originally tried using has_and_belongs_to_many but it wasn't working. After scrummaging through the internet I was convinced that this was not what I needed anyhow. So, I switched to a has_many through method. However, this isn't working either. I am now at a major loss on what the issue is. I have ripped it out many times and tried tutorial after tutorial but to no avail.

The models I am trying to connect are Message and Author. In my most recent attempt, I created a joining model (with corresponding table) called Authoring. Here is my code:

message.rb

    has_many :authorings
    has_many :authors, through: :authorings

author.rb

    has_many :authorings
    has_many :messages, through: :authorings

authoring.rb

    belongs_to :message
    belongs_to :author

messages_controller.rb

    def messages_params
        params.require(:message).permit(:title, :summary, :date, :duration, :youversion, :hours, :minutes, :seconds, :authors)
    end

My Messages form:

    <%= f.label :speakers %><br /> 
    <%= collection_select(:authors, :authors, Author.all, :id, :name, {}, {:multiple => true, :size => 10}) %>

When I created a new message, this showed in the log:

     Parameters: {"utf8"=>"✓", "authenticity_token"=>"OcLeke/eRRzwApoMSgQF81kBCm7TaGxW1PoVAUgEcvo=", "message"=>{"title"=>"Test1", "summary"=>"This is my test summary.", "date(2i)"=>"8", "date(3i)"=>"25", "date(1i)"=>"2014", "date(4i)"=>"01", "date(5i)"=>"00", "hours"=>"0", "minutes"=>"58", "seconds"=>"52", "youversion"=>""}, "authors"=>{"authors"=>["", "1"]}, "commit"=>"I'm Finished", "id"=>"1"}

The form obviously recognizes the authors in the form but it doesn't save them in the database. What is my disconnect? Please help!!!

Thanks!

Upvotes: 0

Views: 94

Answers (1)

Kirti Thorat
Kirti Thorat

Reputation: 53048

authors records are not getting created because the controller is expecting authors to be present within message key's value in params hash BUT if you notice the params hash in the log

Parameters: {"utf8"=>"✓", "authenticity_token"=>"OcLeke/eRRzwApoMSgQF81kBCm7TaGxW1PoVAUgEcvo=", "message"=>{...}, "authors"=>{...}, "commit"=>"I'm Finished", "id"=>"1"}

you would see that authors is coming as an altogether separate key in params hash which is why it is being ignored.

What you need to do is associate the authors with the form object, instead of using collection_select you need to use f.collection_select as shown below. Specify the first argument as :author_ids in f.collection_select.

<%= f.collection_select(:author_ids, Author.all, :id, :name, {}, {:multiple => true, :size => 10}) %>

As you have :multiple => true option specified, you would receive authors as an Array in the params hash. You need to permit author_ids as an Array in message_params method

def messages_params
    params.require(:message).permit(:title, :summary, :date, :duration, :youversion, :hours, :minutes, :seconds, :author_ids => [])
end

Upvotes: 1

Related Questions