Search code examples
ruby-on-railshas-and-belongs-to-many

How to fix error with has_and_belongs_to_many creation in rails


I want to create a record in join table but rails shows me two errors in two situation, and I don't want to generate a third model.

@channel = Channel.find(params[:channel_id])
 if @channel.users.create!(channel_id: params[:channel_id], user_id: params[:user_id])
     flash[:success] = "U Succeed:)"
     redirect_to request.referrer
 else
     flash[:danger] = "U Nit Succeed:H"
     redirect_to request.referrer
 end

second situation

 if Channel.users.create!(channel_id: params[:channel_id], user_id: params[:user_id])
     flash[:success] = "U Succeed:)"
     redirect_to request.referrer
 else
     flash[:danger] = "U'r Not Succeed:H"
     redirect_to request.referrer
 end

I want to save attrs in join table. According to rails official site guide, what's wrong?

First error:

unknown attribute 'channel_id' for User.

Second error:

undefined method `users' for Class:0x00007feaa0312058


Solution

  • I am assuming that you have associations like these:

    class User < ActiveRecord::Base
      has_and_belongs_to_many :channels
    end
    
    class Channel < ActiveRecord::Base
      has_and_belongs_to_many :users
    end
    

    Now you are trying to do like this:

    @channel.users.create!(channel_id: params[:channel_id], user_id: params[:user_id])
    

    This will try to create a new User class object as there is no Model in between you just have a mid table. Instead you can do it like this:

    # If you don't have the user object already
    user = User.find params[:user_id]
    
    # This will create a record in the mid table
    @channel.users << user
    

    This will create a new record in the mid table and the existing records will also exist as it is. And if you do like this:

    @channel.users = user
    

    This will delete all the existing associated user records from the mid table for this channel and add a new associated record with this user.

    And when you try doing like this:

    Channel.users.create!(channel_id: params[:channel_id], user_id: params[:user_id])
    

    This is not valid at all because the class Channel doesn't have any direct relation with the User but an instance of Channel class may be associated with instances of User class.