0

I am working on a project that has the need for a has_and_belongs_to_many relation.

This involves Users having many "proposals" and a proposal belonging to many users.

This is important as a user can create a proposal, and invite other users to it.

I am having trouble setting this up correctly, have read many other tutorials and SO questions but cannot get it sorted.

Here is what I have so far.

User.rb

class User < ActiveRecord::Base
  has_and_belongs_to_many :proposals
 .......


Proposal.rb

class Proposal < ActiveRecord::Base
  has_and_belongs_to_many :users
...


database migration for HABTM

class CreateProposalUserJoinTable < ActiveRecord::Migration
  def change

  create_table :proposals_users, :id => false do |t|
    t.integer :user_id
    t.integer :proposal_id
  end
  end
end


/views/proposals/_form.html.erb
...
<%= f.collection_select(:users, User.all, :id, :trading_name) %>

<%= f.collection_select(:users, User.all, :id, :trading_name) %>

<%= f.collection_select(:users, User.all, :id, :trading_name) %>

...

This is where I want the user to select three users, and them be added to the relationship.

I have tried adding this logic to the controller, but cannot get it working correctly.

Originally I had hacked it together with id's as foreign keys, but would like to use active record associations.

[EDIT]

proposals_controller.rb
 def create
    @proposal = Proposal.new(params[:proposal])

    if current_user
     @user = current_user

     @proposal.creator_id = @user.id
     @proposal.cost = 10


    end

    respond_to do |format|
      if @proposal.save


       (params[:proposal][:users]).each do |user|
          if user.to_i.to_s == user || user.to_f.to_s == user
            puts user 
            puts "********************\n\n\n\n\n\n\n"
            @proposal.users = User.find(user)

         User.find(user).proposals << @proposal
        end
        end
        @proposal.save
        format.html { redirect_to @proposal, notice: 'proposal was successfully created.' }
        format.json { render json: @proposal, status: :created, location: @proposal }
      else
        format.html { render action: "new" }
        format.json { render json: @proposal.errors, status: :unprocessable_entity }
      end
    end

  end
JamesWatling
  • 1,175
  • 1
  • 9
  • 17
  • Ends up this is working in the console just fine, but I have a problem with my collection_select. I need it to return the user, not the id of the user... In the parameters when it crashes, it has users => 1, (for user id one) when I need the user model. – JamesWatling Nov 27 '12 at 01:21
  • But even if I add a hidden field to assign the value of users to a user (id ==1) it throws this error: undefined method `each' for "#":String – JamesWatling Nov 27 '12 at 01:24

1 Answers1

3

It is not necessary to assign users to a proposal. Instead, you can also assign ids, like this:

proposal.user_ids = params[:proposal][:user_ids]

In following code, the assignment is done automatically:

proposal.attributes = params[:proposal]

To make this work, the view should be changed like this:

<%= select_tag("proposal[user_ids][]", options_from_collection_for_select(User.all, :id, :trading_name)) %>
Yanhao
  • 5,264
  • 1
  • 22
  • 15
  • I get this response on changing as above: 'NoMethodError in ProposalsController#create undefined method `proposals' for #' – JamesWatling Nov 27 '12 at 20:06
  • i am facing a similar problem with rails4. can you please help me out - http://stackoverflow.com/questions/24342275/rails-4-has-belongs-to-many – Harsha M V Jun 21 '14 at 14:22