Hi everybody!
Here are trunks of models from a little rails app I'm developing:
###########################
class Country < ActiveRecord::Base
has_many :companies
........
###########################
class Category < ActiveRecord::Base
has_many :companies
........
###########################
class Company < ActiveRecord::Base
has_many :employees , :dependent => true
belongs_to :country, :counter_cache => true
belongs_to :category, :counter_cache => true
........
###########################
class Employee < ActiveRecord::Base
belongs_to :company, :counter_cache => true
........
###########################
I just would like to know: The right way to create a new company by updating
Country.find(id).companies.size is by doing
Country.find(id).companies.create . Right?
1) But what if I'd like to keep in cache companies.size for the category in
which the new company is put? I can't create a company simultaneously using
two parents!
2) When I edit the properties of a company, let's say moving from Japan to
Italy, how could I update Japan.companies_count and Italy.companies_count?
I tried to modify the update action of CompanieController:
###########################
def update
@company = Company.find(params[:id])
@oldcountry=@company.country
if @company.update_attributes(params[:company])
@newcountry=@company.country
@oldcountry.companies_count=@oldcountry.companies(:refresh).size
@newcountry.companies_count=@newcountry.companies(:refresh).size
flash[:notice] = 'Company was successfully updated.'
redirect_to :action => 'show', :id => @company
else
render :action => 'edit'
end
end
###########################
but that did'nt work. :(
3) Is there a Rails' way to cache the number of Employees directly in
Company.employees_count and Category.employees_count (i.e. through
a "has_many_many" relation)? That would prevent iterating through every
company of a given country/category to get its .employees_count!
Thanks a lot for your attention,
Have a good night,
Eric
|
|
0
|
|
|
|
Reply
|
eric.duminil (17)
|
8/28/2006 8:27:03 PM |
|
I think you want the Rails mailing list...
Max
On 8/29/06, =C9ric DUMINIL <eric.duminil@gmail.com> wrote:
> Hi everybody!
>
> Here are trunks of models from a little rails app I'm developing:
>
> ###########################
> class Country < ActiveRecord::Base
> has_many :companies
> ........
>
> ###########################
> class Category < ActiveRecord::Base
> has_many :companies
> ........
>
> ###########################
> class Company < ActiveRecord::Base
> has_many :employees , :dependent =3D> true
> belongs_to :country, :counter_cache =3D> true
> belongs_to :category, :counter_cache =3D> true
> ........
>
> ###########################
>
> class Employee < ActiveRecord::Base
> belongs_to :company, :counter_cache =3D> true
> ........
>
> ###########################
>
>
> I just would like to know: The right way to create a new company by updat=
ing
> Country.find(id).companies.size is by doing
> Country.find(id).companies.create . Right?
>
> 1) But what if I'd like to keep in cache companies.size for the category =
in
> which the new company is put? I can't create a company simultaneously usi=
ng
> two parents!
>
> 2) When I edit the properties of a company, let's say moving from Japan t=
o
> Italy, how could I update Japan.companies_count and Italy.companies_coun=
t?
> I tried to modify the update action of CompanieController:
>
> ###########################
>
> def update
> @company =3D Company.find(params[:id])
> @oldcountry=3D@company.country
> if @company.update_attributes(params[:company])
> @newcountry=3D@company.country
> @oldcountry.companies_count=3D@oldcountry.companies(:refresh).size
> @newcountry.companies_count=3D@newcountry.companies(:refresh).size
> flash[:notice] =3D 'Company was successfully updated.'
> redirect_to :action =3D> 'show', :id =3D> @company
> else
> render :action =3D> 'edit'
> end
> end
>
> ###########################
>
> but that did'nt work. :(
>
>
> 3) Is there a Rails' way to cache the number of Employees directly in
> Company.employees_count and Category.employees_count (i.e. through
> a "has_many_many" relation)? That would prevent iterating through every
> company of a given country/category to get its .employees_count!
>
> Thanks a lot for your attention,
>
> Have a good night,
>
> Eric
>
>
>
>
>
|
|
0
|
|
|
|
Reply
|
ruby1321 (41)
|
8/28/2006 10:13:13 PM
|
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
�ric DUMINIL wrote:
> I just would like to know: The right way to create a new company by updating
> Country.find(id).companies.size is by doing
> Country.find(id).companies.create . Right?
This is one way of doing it. Although if you have the id of the Country
you can just say:
company = Company.create( :company_name=>'ABC Co', :country_id=>1 )
OR
company = Company.new( :company_name=>'ABC Co', :country_id=>1 )
company.save
Both of these will update the country countries_counter because you have
defined this in your belongs_to relationship.
>
> 1) But what if I'd like to keep in cache companies.size for the category in
> which the new company is put? I can't create a company simultaneously using
> two parents!
This can be solved using create or save on Company itself, rather then
doing Country.find.companies.create. Since you have defined the
belongs_to relationship and specified the counter cache ActiveRecord
will be smart enough to update both of them. The following example will
work:
Company.create :company_name=>'ABC', :country_id=>1, :category_id=>1
>
> 2) When I edit the properties of a company, let's say moving from Japan to
> Italy, how could I update Japan.companies_count and Italy.companies_count?
If you edit the properties of a company and save it ActiveRecord will
correctly increment/decrement the counter cache fields that you have
placed on your tables.
Using :refresh will ensure that you get the most recent data from the
database.
>
> 3) Is there a Rails' way to cache the number of Employees directly in
> Company.employees_count and Category.employees_count (i.e. through
> a "has_many_many" relation)? That would prevent iterating through every
> company of a given country/category to get its .employees_count!
I don't know about the count via a another relationship, but you can
always count them at once rather then iterating over each company.
Category.count(
:joins=>"INNER JOIN #{Company.table_name} ON " +
"#{Company.table_name}.category_id=" +
"#{Category.table_name}.id " +
"INNER JOIN #{Employee.table_name} ON " +
"#{Employee.table_name}.company_id=#{Company.table_name}.id",
:group=>"#{Category.table_name}.id" )
This will give you an array of arrays, where each internal array is
employee_count, category_id:
[ [ 4, 1 ], [ 2, 2 ], [ 30, 3 ] ]
It doesn't handle categories that do not have any employees although
that could be fixed.
This is perhaps not as simple of a solution you're looking for. Perhaps
someone else knows if you can do counter_cache using :through. ;)
Zach
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFE86bfMyx0fW1d8G0RAukPAJ9h4COcF11Zrzo0AVqjV1t8Il1hjACfcbuQ
7Qqh6h2BI4zt9P8WjMq59cg=
=Nz8h
-----END PGP SIGNATURE-----
|
|
0
|
|
|
|
Reply
|
zdennis (552)
|
8/29/2006 2:28:27 AM
|
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
zdennis wrote:
>
> This is one way of doing it. Although if you have the id of the Country
> you can just say:
> company = Company.create( :company_name=>'ABC Co', :country_id=>1 )
> OR
> company = Company.new( :company_name=>'ABC Co', :country_id=>1 )
> company.save
>
> Both of these will update the country countries_counter because you have
^^^^^^^^^^^^^^^
should be companies_counter. ;)
Zach
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFE86hbMyx0fW1d8G0RAsWHAJ0XsQqlFXZePu0A+xXdsw3FRn4DfQCfUAyX
xNpxNiX3RqhDAfutQC3Ud1k=
=P1Yo
-----END PGP SIGNATURE-----
|
|
0
|
|
|
|
Reply
|
zdennis (552)
|
8/29/2006 2:34:55 AM
|
|
|
3 Replies
46 Views
(page loaded in 0.147 seconds)
Similiar Articles:7/30/2012 8:13:44 AM
|