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