Forum: Ruby on Rails HABTM: deleting records based on attributes

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
3402be74d2217f237067f6aa4f86fa66?d=identicon&s=25 Paul Hudson (phudson1442)
on 2005-11-16 05:18
Hello All,

I am new to ROR, and can't seem to get HABTM to cooperate entirely...
however I might be abusing it!  Before I try a different strategy I
thought I'd ask here and see if I'm missing something simple.

So say Projects and Companies are related.  Projects can have multiple
Companies, and Companies can be on multiple Projects.  But, the same
Company can also be assigned multiple times to the same Project under
different roles.

This all works fine with something like this:

@project.companies.push_with_attributes(company, :role_id =>
params[:role_id])

So I make 2 entries for a Company.  One with the role of 'shipping', and
one with the role of 'distribution'.  Now how do I remove only one of
the entries?  I can only seem to find ways to remove Companies from a
Project based on company_id (which deletes both entries).

@project.companies.delete(company)

I need to be able to do it based on company_id and role_id.


Here are my models:

class Company < ActiveRecord::Base
      has_and_belongs_to_many :projects
      belongs_to :role
end

class Project < ActiveRecord::Base
      has_and_belongs_to_many :companies
      belongs_to :role
end

class Role < ActiveRecord::Base
      has_many :companies
      has_many :projects
end


I feel like I'm really close or else way off, but not sure which ;)


Thanks for your help,
Paul
A2c85dc5ee81b12e3cc0a6522e8d079d?d=identicon&s=25 christopher.k.hall (Guest)
on 2005-11-16 20:46
(Received via mailing list)
you might want to tackle this from another angle...here's how i would do
it.
not saying its the best way, just that it makes more sense to me...

db schema:

companies
----------
id
name
pk (id)

projects
----------
id
name
pk (id)

roles
----------
id
name
pk (id)

company_project_relationships
----------
id
company_id
project_id
role_id
pk (id)
unique (company_id, project_id, role_id)
fk (company_id)
fk (project_id)
fk (role_id)

class definitions:

class Company < ActiveRecord::Base
has_many :project_relationships, :class_name =>
"CompanyProjectRelationship", :dependent => :destroy

def add_project_relationship(project, role)
project_relationships.create(:company_id => id, :project_id =>
project.id<http://project.id>,
:role_id => role.id <http://role.id>) unless
project_relationships.find(id,
:conditions => ["project_id = ? and role_id = ?",
project.id<http://project.id>,
role.id <http://role.id>])
end

def remove_project_relationship(project, role)
pr = CompanyProjectRelationship.find(:first, :conditions => ["company_id
= ?
and project_id = ? and role_id = ?", id, project.id <http://project.id>,
role.id <http://role.id>])
project_relationships.delete(pr) unless cpr.nil?
end
end

class Project < ActiveRecord::Base
has_many :company_relationships, :class_name =>
"CompanyProjectRelationship", :dependent => :destroy

def add_company_relationship(company, role)
company_relationships.create(:company_id => company.id
<http://company.id>,
:project_id => id, :role_id => role.id <http://role.id>)
end

def remove_company_relationship(company, role)
cr = CompanyProjectRelationship.find(:first, :conditions => ["company_id
= ?
and project_id = ? and role_id = ?", company.id <http://company.id>, id,
role.id <http://role.id>])
ccompany_relationships.delete(cr) unless cpr.nil?
end
end

class CompanyProjectRelationship < ActiveRecord::Base
belongs_to :role
belongs_to :company
belongs_to :project
end

class Role < ActiveRecord::Base
has_many :cprs, :class_name => "CompanyProjectRelationship"
end


given the following data:

companies = 1, 'Company A' and 2, 'Company B'
projects = 1, 'Project 1' and 2, 'Project 2'
roles = 1, 'shipper' and 2, 'distributer'

you could do:

project = Project.find(1)
companies = Company.find(:all)
roles = Roles.find(:all)

project.add_company_relationship(companies[0], roles[0])
project.add_company_relationship(companies[0], roles[1])

this will add 2 rows to company_project_relationships table, making
Company
A both the shipper and distributer for Project 1

to remove a particular relationship, just do:

project.remove_company_relationship(company, roles[0]) ... or ...
companies[0].remove_project_relationships(project, role[0])

this would remove Company A as the shipper for Project 1

note, since this was just an example, there's no real error checking.

hope this helps...

Chris
This topic is locked and can not be replied to.