Why not associations without an extra table?

I'm new and I just trying to figure out something about associations. The following ruby code works but does not work in my actual rails application. Am I doing something wrong or is there a reason why I need to always use an extra table for a has_many_and_belongs_to relationship? When I try this is Rails its willing to do a part of this (e.g, e.department) but not the last '.customers' part? I could of course just to x = e.department and then do x.customers (which does work in Rails) but why do I need to do this in two steps instead of one? I can see that for large datasets why the additional table would help but if the dataset is small why do you need the extra table/ steps?

  require 'rubygems';require 'active_record'; require 'mysql';   ActiveRecord::Base.establish_connection(:adapter => 'mysql', :database => "idea", :username => "myname", :password => 'mypswd')

class Employee < ActiveRecord::Base   belongs_to :department end class Department < ActiveRecord::Base   has_many :departments   has_many :comments end class Customers < ActiveRecord::Base   belongs_to :department end e = Employee.find(1) #to find the number of customers associated with a particular employee within a department p e.department.customers.size

In the code posted Department model

has_many: departments

Should it not be has_many:customers???

Regards,

Naren

Looks to me that you don't have the right model relationships defined.

in order to do "e.department.customers", the Department class has to know about the relationship with Customers. You should have:

class Department < AR::Base   has_many :customers end

I think this should work, if everything else is set up properly.

If this doesn't work, ensure that you have the proper table fields defined as well. You will need a "department_id" field in the customers table.

Also, the rails convention is to name model classes with the singular version of the name. So you will likely also want to change the class name to

class Customer < AR::Base   #... end

This can be changed, but with what you provide, I don't see that you changed it.

Good luck

Andrew

require 'rubygems';require 'active_record'; require 'mysql'; ActiveRecord::Base.establish_connection(:adapter => 'mysql', :database => "idea", :username => "myname", :password => 'mypswd')

class Employee < ActiveRecord::Base belongs_to :department end class Department < ActiveRecord::Base has_many :departments - has_many :comments       + has_many :customers end class Customer < ActiveRecord::Base belongs_to :department end

> e = Employee.find(1) > #to find the number of customers associated with a particular employee > within a department > p e.department.customers.size

Sorry, those were typos. Customer is singular and there is no comments database just a customers one. That is, comments should have been customers. As noted, the program does work perfectly, except in Rails and of course it couldn't possibly be a problem of ids because I can get it to work in Rails as well but only if I use a two step procedure. As noted, x = e.department and then x.customers.size

Therefore, it is not a problem of ids as it works in rails 2.3.5, it just takes two steps but why two steps instead of one?

Give us more code, because this can be done in a single step.

Chaining method calls like that will return a single department object (e.department). So it should be no different, and I have done similar things in the past without trouble.

The only time this shouldn't work is if you try something like e.departments.customers. This is because the plural "departments" means you will return multiple departments. That collection will not have a single ".customers" method.

I figured out why is doesn't work and to my great shame, I'd actually read this article http://blog.hasmanythrough.com/2008/2/27/count-length-size

In rails, you need to use .count and not .size for this to work because the first collection has already been loaded and therefore you are asking for the length and not the count! The length == 0 and so no records are returned.

I don't understand. Length, size, and count should all return the same value; the difference is in the SQL generated (or not generated). Why is the length 0?