2

I've been back on rails after long period on other techno, and it appears i'm a bit rusty.

I've been trying to handle Project, Client and Contact and I'm a little confused by the results.

At first I had just one "contact_id" in my Project and everything was find, but I figured out I'd really love to have multiple contacts for one project.

So this is what i've been trying :

Project model:

class Project < ActiveRecord::Base
  belongs_to :owner, class_name: User, foreign_key: "owner_id"
  belongs_to :worker, class_name: User, foreign_key: "worker_id"
  #  belongs_to :contact, class_name: Contact, foreign_key: "contact_id"
  has_many :project_contacts
  has_many :contacts, :through => :project_contacts
  has_many :tasks
  has_many :feedbacks
  before_save :set_estimated_time
  #pleinty of utilities
end

Contact model:

class Contact < ActiveRecord::Base
  belongs_to :client, class_name: Client, foreign_key: "client_id"
  has_manny :project_contacts
  has_many :projects, :through => :project_contacts
end

ProjectContact model:

class ProjectContact < ActiveRecord::Base
  belongs_to :project
  belongs_to :contact
end

I thought it was ok but here's what I get when I use Rails console:

2.2.3 :001 > project = Project.find(31) Project Load (0.3ms) SELECT 'projects'.* FROM 'projects' WHERE 'projects'.'id' = 31 LIMIT 1 => # 2.2.3 :002 > project.contacts NameError: uninitialized constant Project::ProjectContact

Edit :

Contact migration

class AddProjectContacts < ActiveRecord::Migration
  def change
    create_table :project_contacts do |pc|
      pc.belongs_to :project, index: true
      pc.belongs_to :contact, index: true
      pc.timestamps null: false
    end
  end
end

I'd really appreciate any help with this

Bye

galettan
  • 75
  • 8
  • 1
    Did you run the migration? (I know stupid question, but you never know). Also, what does projet.project_contacts return? This association has to work before you can run project.contacts. Also for this kind of associations, if you don't need to do something special in your ProjectContact model, you should rather use has_and_belongs_to_many: http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association – Kulgar Oct 21 '15 at 13:30
  • Yes I did run the migration (i also inserted 1 row manualy to have a record). project.project_contacts return "undefined method" – galettan Oct 21 '15 at 13:32
  • Should I add a foreign_key like : add_foreign_key :projectcontacts, :projects, column: :project_id, on_delete: :nullify for project and contact ? – galettan Oct 21 '15 at 13:35
  • No I don't think you have to do that... Hmm... Let me test your code :) – Kulgar Oct 21 '15 at 13:37
  • Thank you :-). Really hard to get back on rails on its own =] – galettan Oct 21 '15 at 13:39
  • I always recommend reading this book: https://www.railstutorial.org/book - you can upgrade your skills for free ;) – Kulgar Oct 21 '15 at 13:40
  • Could you also add project-relative paths to model files? – D-side Oct 21 '15 at 13:43
  • Basically there are all in app/models folder. – galettan Oct 21 '15 at 13:45
  • Your code work for me... that is so strange. I found a similar issue here: http://stackoverflow.com/questions/7040022/rails-why-has-many-through-association-results-in-nameerror-un but you don't seem to have the same convention problem here as you did not put any "s" at the end of the model classname... – Kulgar Oct 21 '15 at 13:50
  • Ok "have you tried turning it off and on again" issue i guess. I've seen this question alreaddy i was not sure of my spelling with class like ProjectContact, but i thought it was OK. I'm running ruby 2.2.3 and rails 4.2.4 btw. – galettan Oct 21 '15 at 13:53
  • Your spelling is ok I think... I think I would rather have used something with more meaning like: "ProjectManager" or "ProjectParticipant" for the join model, as "Contact" is a little bit too generic... but the issue is not linked to the spelling I think... Maybe try with another model name for the join model? Also try to comment everything in your models except for the lines needed to set the association, just to have some "clean models" and let us know if it solves anything. :) – Kulgar Oct 21 '15 at 14:00
  • Thank you Kuglar, just changed the table / class name and it works perfectly. \o/ – galettan Oct 21 '15 at 14:20

3 Answers3

1

You have a typo in class Contact: has_many and not has_manny.

Brozorec
  • 1,163
  • 9
  • 15
1

Ok so i just changed the class name to "participant" to try and everything is fine. :-|

galettan
  • 75
  • 8
  • 2
    According to rails conventions the original table should have been projects_contacts (this is what is expected by a has_and_belongs_to_many association). But as you used the "through" association with a properly configured table name... it's weird it didn't work in the first place. As I said I tested it with those exact names and it worked for me... really really strange it did not work for you. – Kulgar Oct 21 '15 at 14:41
  • Can you post your new models? – Richard Peck Oct 21 '15 at 14:41
  • The key is `Project::ProjectContact` – Richard Peck Oct 21 '15 at 14:41
1

For posterity, here's how I'd expect it to look:

#app/models/project.rb
class Project < ActiveRecord::Base
   has_many :project_contacts
   has_many :contacts, through: :project_contacts
end 

#app/models/project_contact.rb
class ProjectContact < ActiveRecord::Base
   #columns id | project_id | contact_id | created_at | updated_at
   belongs_to :project
   belongs_to :contact
end

#app/models/contact.rb
class Contact < ActiveRecord::Base
   has_many :project_contacts
   has_many :projects, through: :project_contacts
end

This should give you the ability to call:

@project = Project.find params[:id]
@project.contacts #-> shows all contacts
Richard Peck
  • 76,116
  • 9
  • 93
  • 147