Jean-Christophe Michel
2005-Aug-28 20:51 UTC
strange difference between has_one and has_many
Hi,
I don''t know rails enough to decide wether this is a bug or feature.
I have two models, Menu and MenuText (many langs, so many texts per
menu). (see sql below)
If I define has_many:
class Menu < ActiveRecord::Base
has_many :menu_texts, :conditions => [''lang = ?'',
''fr'']
end
class MenuText < ActiveRecord::Base
belongs_to :menu
end
then
Menu.find(1).menu_texts.first shows the unique menu_text associated to
the menu.
no pb, everything works.
But if I change to has_one:
class Menu < ActiveRecord::Base
has_one :menu_text, :conditions => [''lang = ?'',
''fr'']
end
then
Menu.find(1).menu_text raises an error (array to string conversion)
It''s due to the difference of treatment that conditions receive in both
associations code:
active_record/associations/has_many_association.rb:
@finder_sql << " AND #{interpolate_sql(@conditions)}" if
@conditions
active_record/associations/has_one_association.rb, li 68:
#{@options[:conditions] ? " AND " + @options[:conditions].
Why does has_one treat conditions differently?
Isn''t it a bug ?
SQL:
CREATE TABLE menus (
id BIGSERIAL NOT NULL,
-- Some statistics about the user data
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
...
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES menus (id) ON DELETE RESTRICT
);
CREATE TABLE menu_texts (
id BIGSERIAL NOT NULL,
menu_id BIGINT NOT NULL,
-- Real information: lang, title
lang CHARACTER (2) NOT NULL DEFAULT ''fr'',
title CHARACTER VARYING (200) NOT NULL,
FOREIGN KEY (menu_id) REFERENCES menus (id) ON DELETE CASCADE
);
--
Jean-Christophe Michel
Jean-Christophe Michel wrote:>Hi, > >I don''t know rails enough to decide wether this is a bug or feature. > > >Feature.>I have two models, Menu and MenuText (many langs, so many texts per >menu). (see sql below) > >If I define has_many: > >class Menu < ActiveRecord::Base > has_many :menu_texts, :conditions => [''lang = ?'', ''fr''] >end >class MenuText < ActiveRecord::Base > belongs_to :menu >end > >then > Menu.find(1).menu_texts.first shows the unique menu_text associated to >the menu. >no pb, everything works. > > >You said there are many, so menu_texts (note the plural) returns an array.>But if I change to has_one: >class Menu < ActiveRecord::Base > has_one :menu_text, :conditions => [''lang = ?'', ''fr''] >end > >then > Menu.find(1).menu_text raises an error (array to string conversion) > > >You said it has one, so menu_text (no plural) returns a single object.>It''s due to the difference of treatment that conditions receive in both >associations code: > > active_record/associations/has_many_association.rb: > @finder_sql << " AND #{interpolate_sql(@conditions)}" if @conditions > > active_record/associations/has_one_association.rb, li 68: > #{@options[:conditions] ? " AND " + @options[:conditions]. > >Why does has_one treat conditions differently? > >
Jean-Christophe Michel
2005-Aug-30 20:39 UTC
Re: strange difference between has_one and has_many
Hi Steve I''m not sure you got my point ;-) Steve Downey wrote:>> I have two models, Menu and MenuText (many langs, so many texts per >> menu). (see sql below) >> >> If I define has_many: >> >> class Menu < ActiveRecord::Base >> has_many :menu_texts, :conditions => [''lang = ?'', ''fr''] >> end >> class MenuText < ActiveRecord::Base >> belongs_to :menu >> end >> >> then >> Menu.find(1).menu_texts.first shows the unique menu_text associated to >> the menu.> You said there are many, so menu_texts (note the plural) returns an array.Sure, as I wrote: >> no pb, everything works.>> But if I change to has_one: >> class Menu < ActiveRecord::Base >> has_one :menu_text, :conditions => [''lang = ?'', ''fr''] >> end >> >> then >> Menu.find(1).menu_text raises an error (array to string conversion)> You said it has one, so menu_text (no plural) returns a single object.No! It raises an error, array to string conversion, whereas of course I''d like to see an object. The error disappear if I replace :conditions => [''lang = ?'', ''fr''] by :conditions => [''lang = fr''] so the reason is clearly in the way conditions are handled.>> It''s due to the difference of treatment that conditions receive in both >> associations code: >> >> active_record/associations/has_many_association.rb: >> @finder_sql << " AND #{interpolate_sql(@conditions)}" if @conditions >> >> active_record/associations/has_one_association.rb, li 68: >> #{@options[:conditions] ? " AND " + @options[:conditions]. >> >> Why does has_one treat conditions differently?-- Jean-Christophe Michel