Hi all, Quick question for STI. With the following setup: class Company < AR::Base; end class Firm < Company; end Why does Firm.find(:all) return all Companies, not just those that have type==''Firm''? -- Alex
On 12/29/05, Alex Young <alex-qV/boFbD8Meu8LGVeLuP/g@public.gmane.org> wrote:> Hi all, > > Quick question for STI. With the following setup: > > class Company < AR::Base; end > class Firm < Company; end > > Why does Firm.find(:all) return all Companies, not just those that have > type==''Firm''?That sounds like a good feature. My naive question would be this: what happens if you define: class BigFirm < Firm; end Does Firm:find :all return instances of BigFirm as well, or just instances of Firm? -- Reginald Braithwaite http://www.braithwaite-lee.com/weblog/ Like all text messages, email exchanged with a gmail account may be stored indefinitely and/or read by third parties without the sender or receiver''s knowledge or permission. Please do not send any privileged or confidential transmission to this account: enquire about secure alternatives. Experience and Treachery will beat Youth and Talent every time.
Reginald Braithwaite wrote:> That sounds like a good feature. My naive question would be this: what > happens if you define: > > class BigFirm < Firm; end > > Does Firm:find :all return instances of BigFirm as well, or just > instances of Firm?Logically, it should... All BigFirms are Firms, after all. -- Alex
On 12/29/05, Alex Young <alex-qV/boFbD8Meu8LGVeLuP/g@public.gmane.org> wrote:> Hi all, > > Quick question for STI. With the following setup: > > class Company < AR::Base; end > class Firm < Company; end > > Why does Firm.find(:all) return all Companies, not just those that have > type==''Firm''? >Having Firm.find(:all) return only entries with type==''Firm'' would mean that there would be some ''implicit'' conditions attached. My wild guess as to why this isn''t done is that it could get very tricky to add that into an arbitrary set of conditions. Firm.find(:all, :conditions => "blah = 1 and thingy = ''y'' ") ..AR would need to add "and type = ''Firm''" to the end of the conditions. Now what happens when you''re doing a more complex condition, possibly involving group by, having, ''partition over'', etc.. knowing where to inject a ''where'' could be sticky. That being said, it would be a cool feature. At the moment, Company.find_all_by_type(''Firm'') is probably the shortest answer.
Wilson Bilkovich wrote:> Having Firm.find(:all) return only entries with type==''Firm'' would > mean that there would be some ''implicit'' conditions attached. > My wild guess as to why this isn''t done is that it could get very > tricky to add that into an arbitrary set of conditions. > Firm.find(:all, :conditions => "blah = 1 and thingy = ''y'' ") > ..AR would need to add "and type = ''Firm''" to the end of the conditions. > Now what happens when you''re doing a more complex condition, possibly > involving group by, having, ''partition over'', etc.. knowing where to > inject a ''where'' could be sticky.True, but the with_scope method already does something similar. In fact, looking through the find() method, it looks like it should be doing it anyway, with the construct_finder_sql() method... Maybe I messed something else up... -- Alex
On 12/29/05, Alex Young <alex-qV/boFbD8Meu8LGVeLuP/g@public.gmane.org> wrote:> Reginald Braithwaite wrote: > > That sounds like a good feature. My naive question would be this: what > > happens if you define: > > > > class BigFirm < Firm; end > > > > Does Firm:find :all return instances of BigFirm as well, or just > > instances of Firm? > Logically, it should... All BigFirms are Firms, after all. >That makes things interesting. find_all_by_type(''Firm'') doesn''t work for this case (nor does implicitly adding WHERE type=''Firm''). One approach would be to walk the class tree at run time, then construct WHERE (type = ''Firm'' OR type = ''BigFirm'' or...). In Ruby, that''s a challenge because there might be a class that hasn''t been seen by the interpreter yet, but there is a row of that type. The obverse approach would be to scan the table (ugh). You could SELECT DISTINCT Company.type and test each type against firm using #kind_of? to get a lits of sub-types. This kind of thing could certainly be done. But if you don''t feel like hacking ActiveRecord, you can probably roll your own domain-specific solution using a mixin. -- Reginald Braithwaite http://www.braithwaite-lee.com/weblog/ Did you know... The longest word in the English language, according to the Oxford English Dictionary, is "pneumonoultramicroscopicsilicovolcanoconiosis".
You''re right, it should use SQL like: SELECT * FROM firms WHERE (firms.`type` = ''Firm'' ). I have seen class loading order cause inconsistent behavior with STI queries, though the effect is the opposite of your problem. For instance, if I also have MultiNationalFirm < Firm, and I run Firm.find_all, I will get Companies, Firms, but not MultiNationalFirms. If I then reference MultiNationalFirm and do the run Firm.find_all again, I will get Companies, Firms, _and_ MultiNationalFirms. BTW, you have "Company < AR::Base" in your example. I assume you just abbreviated "ActiveRecord::Base?" Scott On Dec 29, 2005, at 6:25 AM, Alex Young wrote:> Hi all, > > Quick question for STI. With the following setup: > > class Company < AR::Base; end > class Firm < Company; end > > Why does Firm.find(:all) return all Companies, not just those that > have type==''Firm''? > > -- > Alex > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails
Scott Willson wrote:> You''re right, it should use SQL like: SELECT * FROM firms WHERE > (firms.`type` = ''Firm'' ). I have seen class loading order cause > inconsistent behavior with STI queries, though the effect is the > opposite of your problem. > > For instance, if I also have MultiNationalFirm < Firm, and I run > Firm.find_all, I will get Companies, Firms, but not MultiNationalFirms. > If I then reference MultiNationalFirm and do the run Firm.find_all > again, I will get Companies, Firms, _and_ MultiNationalFirms. >That''s just... odd. Presumably in an SCGI environment that would then be non-deterministic?> BTW, you have "Company < AR::Base" in your example. I assume you just > abbreviated "ActiveRecord::Base?"That''s right. I nicked those examples from the ActiveRecord docs because they''re a little more intuitive than what I''m actually using, which are CSVInsert, LabelledInsert and TestimonialInsert. Don''t ask :-) -- Alex
On Dec 29, 2005, at 10:11 AM, Reginald Braithwaite wrote:> In Ruby, > that''s a challenge because there might be a class that hasn''t been > seen by the interpreter yet, but there is a row of that type.Right, that''s the root cause. In my apps, I''ve been able to effectively work around this by explicitly referencing all my STI classes at start-up (it''s a FXRuby app, not web-based). So, in my init script, I say something like: MultiNationalFirm Firm Company On Dec 29, 2005, at 10:19 AM, Alex Young wrote:> That''s just... odd. Presumably in an SCGI environment that would > then be non-deterministic?Not sure. I wouldn''t be surprised if you see the same behavior there, though.> Wilson Bilkovich wrote: >> My wild guess as to why this isn''t done is that it could get very >> tricky to add that into an arbitrary set of conditions. >> Firm.find(:all, :conditions => "blah = 1 and thingy = ''y'' ") >> ..AR would need to add "and type = ''Firm''" to the end of the >> conditions. >> Now what happens when you''re doing a more complex condition, possibly >> involving group by, having, ''partition over'', etc.. knowing where to >> inject a ''where'' could be sticky. >>I think you are right, too. When you get to this point, you''re at the boundaries of what the ActiveRecord class/pattern can do for you, and it''s time to use explicit SQL. Scitt
Hi Everyone, Just been thinking and working on some problem in Supply Chain and came across a situation. This is like this using single table inheritance I have a single table called company and the active record are like this: class Company < ActiveRecord::Base class Vendor < Company class Customer < Company class Office < Company Then there is another class called Region which is class Region < ActiveRecord::Base now there is many to many relationship between Vendor and Region and there is many to many relationship between Office < Region and also in Customer. Now can I use vendor_id , customer_id and office_id as foreign key or can only use company_id since the table for company is only 1 with primary key id. Thanks for help Vikrant