In a model class, can the target of the has_many :conditions option be a method? For example: class etc. has_many abcs :conditions => :local_conditions private def local_conditions [ "start = :begin_date AND end = :end_date", { :begin_date => "2008-01-01", :end_date => DateTime.now } ] end end -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 5 May 2008, at 21:16, James Byrne wrote:> > In a model class, can the target of the has_many :conditions option > be a > method? For example: > > class etc. > > has_many abcs :conditions => :local_conditions >Not quite like that. But those conditions are interpolated in the context of the model, so for example you can say :conditions => ''start_date > #{@start_date}'' When the association is fetched that will be interpolated in the context of the model. You probably could write :conditions => ''#{local_conditions}'' as long as local conditions returned a string of sql (ie not a hash as shown below) Fred> private > > def local_conditions > [ "start = :begin_date AND end = :end_date", > { :begin_date => "2008-01-01", :end_date => DateTime.now } ] > end > > end > -- > Posted via http://www.ruby-forum.com/. > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung wrote:> Not quite like that. But those conditions are interpolated in the > context of the model, so for example you can say > :conditions => ''start_date > #{@start_date}'' > > When the association is fetched that will be interpolated in the > context of the model. You probably could write > :conditions => ''#{local_conditions}'' > > as long as local conditions returned a string of sql (ie not a hash as > shown below) > > FredWell, yes. I had that working in that exact fashion. The situation that I am now trying to address is I have a large number of associations in serveral models that will share identical conditional SQL fragments and I would like to store these in a single module and call them wherever required. Is there aw way to do this? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> > Is there aw way to do this?Never mind. I completely misunderstood the example given. I will try this out and report back. Thanks again. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I must be missing something obvious. If I have class Model < AR has_many abcs :conditions => [ "start = :start_date", { :start_date => DateTime.now } ] Then this assigns an array to the :conditions key, correct? Is there no way to pass a variable that represents an array with the exact same content to :conditions such that the array contents are assigned to the key? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> Is there no way to pass a variable that represents an array with the > exact same content to :conditions such that the array contents are > assigned to the key?I can get it to work this way: class Model etc. @@active_row = [ "start <= :start_date", { :start_date => DateTime.now } ] has_many abcs :conditions => @@active_row Is there a better/cleaner idiom that works? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi -- On Mon, 5 May 2008, James Byrne wrote:> > James Byrne wrote: > >> Is there no way to pass a variable that represents an array with the >> exact same content to :conditions such that the array contents are >> assigned to the key? > > I can get it to work this way: > > class Model etc. > > @@active_row = [ "start <= :start_date", { :start_date => DateTime.now > } ] > > has_many abcs :conditions => @@active_rowKeep in mind, though, that that will evaluate DateTime.now when it loads the model file, and (depending on what environment you''re in, etc.) may not do it again.> Is there a better/cleaner idiom that works?Good question. I can''t think of one that doesn''t stringify the argument, which makes an array useless. That''s not to say there isn''t a way... but I haven''t come up with it. David -- Rails training from David A. Black and Ruby Power and Light: INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin INTRO TO RAILS June 24-27 London (Skills Matter) See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
David A. Black wrote:> Keep in mind, though, that that will evaluate DateTime.now when it > loads the model file, and (depending on what environment you''re in, > etc.) may not do it again. >Is this a consequence of using a class variable rather than an instance variable in this specific case or is this a general trait deriving from the manner in which Rails caches db calls? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi -- On Tue, 6 May 2008, James Byrne wrote:> > David A. Black wrote: > >> Keep in mind, though, that that will evaluate DateTime.now when it >> loads the model file, and (depending on what environment you''re in, >> etc.) may not do it again. >> > > > Is this a consequence of using a class variable rather than an instance > variable in this specific case or is this a general trait deriving from > the manner in which Rails caches db calls?It''s just a matter of how Ruby parses your file. What you''ve got is: class Model @@active_row = [ "start <= :start_date", { :start_date => DateTime.now } ] has_many :abcs, :conditions => @@active_row end When the file is read in and executed, a value will be assigned to the class variable @@active_row. Then, the method has_many will be executed, with the arguments :abc and { :conditions => ["start <:start_date", { :start_date <= "2008-05-05 21:43:47" } ] } (assuming that''s the date and time at that moment). That string won''t change (unless there''s a reload). So every time you do: m = Model.find(x) abcs = m.abcs you''ll be constraining the abcs collection as being <= 2008-05-05 21:43:47. David -- Rails training from David A. Black and Ruby Power and Light: INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin INTRO TO RAILS June 24-27 London (Skills Matter) See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
David A. Black wrote:> Hi -- > > On Tue, 6 May 2008, James Byrne wrote: > >> variable in this specific case or is this a general trait deriving from >> the manner in which Rails caches db calls? > > It''s just a matter of how Ruby parses your file. What you''ve got is: >I infer from this that finders containing dynamic selection elements have to go into the controllers, or does the same problem arise there as well? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi -- On Tue, 6 May 2008, James Byrne wrote:> > David A. Black wrote: >> Hi -- >> >> On Tue, 6 May 2008, James Byrne wrote: >> >>> variable in this specific case or is this a general trait deriving from >>> the manner in which Rails caches db calls? >> >> It''s just a matter of how Ruby parses your file. What you''ve got is: >> > > I infer from this that finders containing dynamic selection elements > have to go into the controllers, or does the same problem arise there as > well?You can have a finder method that does this (or some variation on this -- it''s just an example): def find_earlier_things self.class.find(:all, :conditions => [...]) end where the ... includes DateTime stuff, and then when you do thing.find_earlier_things, it will go find them and, since the method is being executed, it will evaluated the conditions array on the spot. The problem with the association situation is that the association (has_many) is itself a method, and it only gets called once -- at which point it has to have its arguments in place. The only way to have the arguments update themselves later would be to have one of them be an executable object (Proc or method), and I don''t think there''s a way to insinuate one into the conditions position (though if I''m wrong, or if it''s been added recently and I haven''t noticed, I''d be glad to be corrected). David -- Rails training from David A. Black and Ruby Power and Light: INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin INTRO TO RAILS June 24-27 London (Skills Matter) See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 6 May 2008, at 03:49, David A. Black wrote:> > You can have a finder method that does this (or some variation on this > -- it''s just an example): > > def find_earlier_things > self.class.find(:all, :conditions => [...]) > end > > where the ... includes DateTime stuff, and then when you do > thing.find_earlier_things, it will go find them and, since the method > is being executed, it will evaluated the conditions array on the spot. > The problem with the association situation is that the association > (has_many) is itself a method, and it only gets called once -- at > which point it has to have its arguments in place. The only way to > have the arguments update themselves later would be to have one of > them be an executable object (Proc or method), and I don''t think > there''s a way to insinuate one into the conditions position (though if > I''m wrong, or if it''s been added recently and I haven''t noticed, I''d > be glad to be corrected). >The only way I''m aware of is the interpolation trick (:conditions => ''#{something to evaluate later}''). If you use sanitize_sql you can probably keep on using hash conditions & stuff. Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi -- On Tue, 6 May 2008, Frederick Cheung wrote:> > > On 6 May 2008, at 03:49, David A. Black wrote: >> >> You can have a finder method that does this (or some variation on this >> -- it''s just an example): >> >> def find_earlier_things >> self.class.find(:all, :conditions => [...]) >> end >> >> where the ... includes DateTime stuff, and then when you do >> thing.find_earlier_things, it will go find them and, since the method >> is being executed, it will evaluated the conditions array on the spot. >> The problem with the association situation is that the association >> (has_many) is itself a method, and it only gets called once -- at >> which point it has to have its arguments in place. The only way to >> have the arguments update themselves later would be to have one of >> them be an executable object (Proc or method), and I don''t think >> there''s a way to insinuate one into the conditions position (though if >> I''m wrong, or if it''s been added recently and I haven''t noticed, I''d >> be glad to be corrected). >> > > The only way I''m aware of is the interpolation trick (:conditions => > ''#{something to evaluate later}''). If you use sanitize_sql you can > probably keep on using hash conditions & stuff.I had given up on ''#{}'' because of the problem of having it mush arrays and hashes together for string representation -- but you''re quite right that there''s an escape clause.... So here''s what I''ve got in my little testbed: def self.sanitize_me(array) sanitize_sql(array) end has_many :items, :conditions => ''#{self.class.sanitize_me(["created_at > ?", Time.now])}'' The extra method is because sanitize_sql is protected. Next cup of coffee may or may not produce a way to avoid that rather inelegant workaround :-) (There''s ''send'', of course.) David -- Rails training from David A. Black and Ruby Power and Light: INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin INTRO TO RAILS June 24-27 London (Skills Matter) See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
David A. Black wrote:> > > So here''s what I''ve got in my little testbed: > > def self.sanitize_me(array) > sanitize_sql(array) > end > > has_many :items, > :conditions => ''#{self.class.sanitize_me(["created_at > ?", > Time.now])}'' >When I try this on edge rails then I get this:>> @entity = Entity.find(1)NoMethodError: undefined method `sanitize_me'' for Class:Class from /home/byrnejb/Software/Development/Projects/proforma/app/models/entity.rb:47 from /home/byrnejb/Software/Development/Projects/proforma/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:203:in `load_without_new_constant_marking'' -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> David A. Black wrote: >> >> >> So here''s what I''ve got in my little testbed: >> >> def self.sanitize_me(array) >> sanitize_sql(array) >> end >> >> has_many :items, >> :conditions => ''#{self.class.sanitize_me(["created_at > ?", >> Time.now])}'' >> >I did this instead: has_many :items, :conditions => "#{sanitize_sql([ "created_at > :time_now", { :time_now => DateTime.now } ])}" This throws no errors but, the time value is fixed at the time of first load for all instances. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 6 May 2008, at 15:21, James Byrne wrote:> > James Byrne wrote: >> David A. Black wrote: >>> >>> >>> So here''s what I''ve got in my little testbed: >>> >>> def self.sanitize_me(array) >>> sanitize_sql(array) >>> end >>> >>> has_many :items, >>> :conditions => ''#{self.class.sanitize_me(["created_at > ?", >>> Time.now])}'' >>> >> > > > I did this instead: > > has_many :items, > :conditions => "#{sanitize_sql([ > "created_at > :time_now", { :time_now => DateTime.now } > ])}" >The crucial difference is that you are using double quotes and not single quotes. That is why your conditions are evaluated when the class is loaded and not later on. Fred> This throws no errors but, the time value is fixed at the time of > first > load for all instances. > > -- > Posted via http://www.ruby-forum.com/. > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 6 May 2008, at 15:32, Frederick Cheung wrote:>> >> I did this instead: >> >> has_many :items, >> :conditions => "#{sanitize_sql([ >> "created_at > :time_now", { :time_now => DateTime.now } >> ])}" >> > The crucial difference is that you are using double quotes and not > single quotes. That is why your conditions are evaluated when the > class is loaded and not later on.Forgot to say, that''s also why david''s trick wasn''t working (because that assumes that it is being evaluated in the context of an instance of the class, but by swapping the quotes you make it evaluate at load time and thus in the context of the class) Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung wrote:> On 6 May 2008, at 15:21, James Byrne wrote: > >>>> >> :conditions => "#{sanitize_sql([ >> "created_at > :time_now", { :time_now => DateTime.now } >> ])}" >> > The crucial difference is that you are using double quotes and not > single quotes. That is why your conditions are evaluated when the > class is loaded and not later on. > > FredWell, I would never have realized that problem on my own. However, when I change the outer " to '' then I always throw and undefined method error. ... def self.sql_sanitize_here(array) sanitize_sql(array) end ... has_one :active_client, :class_name => ''Client'', :conditions => ''#{self.class.sanitize_sql_here([ " effective_from <= :date_today AND ( superseded_after > :date_today OR superseded_after IS null ) ", { :date_today => DateTime.now } ])}''>> @entity.active_clientNoMethodError: undefined method `sanitize_sql_here'' for #<Class:0xb7558edc> from /home/byrnejb/Software/Development/Projects/proforma/vendor/rails/activerecord/lib/active_record/base.rb:2550:in `interpolate_sql'' from (eval):1:in `interpolate_sql'' from /home/byrnejb/Software/Development/Projects/proforma/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:139:in `send'' -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 6 May 2008, at 15:52, James Byrne wrote:> > Well, I would never have realized that problem on my own. However, > when > I change the outer " to '' then I always throw and undefined method > error. > > ... > def self.sql_sanitize_here(array) > sanitize_sql(array) > end > ... > has_one :active_client, :class_name => ''Client'', > :conditions => ''#{self.class.sanitize_sql_here([These need to match. You''ve defined sql_sanitize_here but are using sanitize_sql_here Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung wrote:> On 6 May 2008, at 15:52, James Byrne wrote: >> ... >> has_one :active_client, :class_name => ''Client'', >> :conditions => ''#{self.class.sanitize_sql_here([ > > > These need to match. You''ve defined sql_sanitize_here but are using > sanitize_sql_here > > FredArrgggh! Yes, this now works. Many thanks for your assistance. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Now that this is working I wish to get the code out of the association and put it in one place where I can easily reuse it across models and associations. Is this possible? One thought that I had earlier envisaged creating a virtual attribute on the Client model called active? and putting the code in there but, this fails on two counts: 1, the presence of a ? in the method name causes problems with the SQL engine in sqlite3 ( I have not tested this on PostgreSQL); and 2, virtual attributes cannot of course be evaluated during the SQL call (although one could argue that the association finders should in fact go through the dependent class and do exactly that because this sort of logic belongs in the model directly providing the where parameters). It seems that the tidiest solution from the standpoint of rails coding and maintenance is to simply add an column named active of type boolean to the model and set it to true or false in accordance with the values in effective_date and superseded_date, which seems a bit redundant but easier to check. Comments? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Assuming that you''ve been consistent in the begin/end date column names, you could/should create a module that you can include in the models that need this functionality. It''d look something like this: module ActivatedObject def self.included(base) base.extend ClassMethods end module ClassMethods def sanitize_sql_here(array) sanitize_sql array end def has_activated_object(class_name) self.has_one "active_#{class_name.to_s}", :class_name => class_name.to_s.classify, :conditions => ''#{self.class.sanitize_sql_here ... }'' end def has_activated_collection(collection_name) self.has_many "active_#{collection_name.to_s}", :class_name => collection_name.to_s.classify, :conditions => ''#{self.class.sanitize_sql_here ... }'' end end end With that in place you would: class ClassWithActivatedAssociation < ARec::Base include ActivatedObject has_activated_object :client has_activated_collection :payment_to_group_helpers # :) ... end On May 6, 12:54 pm, James Byrne <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Now that this is working I wish to get the code out of the association > and put it in one place where I can easily reuse it across models and > associations. Is this possible? > > One thought that I had earlier envisaged creating a virtual attribute on > the Client model called active? and putting the code in there but, this > fails on two counts: 1, the presence of a ? in the method name causes > problems with the SQL engine in sqlite3 ( I have not tested this on > PostgreSQL); and 2, virtual attributes cannot of course be evaluated > during the SQL call (although one could argue that the association > finders should in fact go through the dependent class and do exactly > that because this sort of logic belongs in the model directly providing > the where parameters). > > It seems that the tidiest solution from the standpoint of rails coding > and maintenance is to simply add an column named active of type boolean > to the model and set it to true or false in accordance with the values > in effective_date and superseded_date, which seems a bit redundant but > easier to check. > > Comments? > > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Sometimes, you just have to change tools: @active = ''( effective_from <= current_date AND ( superseded_after IS NULL OR superseded_after >= current_date ))'' ... has_one :buying_client, :class_name => ''Client'', :conditions => @active "current_date", being a standard SQL function evaluated on each call, works perfectly for this situation. Now the question is: Is there a place to put this so that all models can use it without having to specifically include a module or redefine the instance variable in each class? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
James, The pattern that I posted above is one that''s often used in ARec ''acts'' extensions. You could go the plugin route with the code (adding what''s necessary to create the instance variable). Alternately you could keep it in lib and add ActiveRecord::Base.send :include, ''ActivatedObject'' at the end of the file to inject the has_active_xxx methods to ActiveRecord. A HTH, AndyV On May 6, 4:27 pm, James Byrne <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Sometimes, you just have to change tools: > > @active = ''( effective_from <= current_date > AND > ( superseded_after IS NULL OR superseded_after >> current_date ))'' > > ... > > has_one :buying_client, :class_name => ''Client'', > :conditions => @active > > "current_date", being a standard SQL function evaluated on each call, > works perfectly for this situation. > > Now the question is: Is there a place to put this so that all models can > use it without having to specifically include a module or redefine the > instance variable in each class? > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
AndyV wrote:> James, > > The pattern that I posted above is one that''s often used in ARec > ''acts'' extensions. You could go the plugin route with the code > (adding what''s necessary to create the instance variable). > Alternately you could keep it in lib and add > > ActiveRecord::Base.send :include, ''ActivatedObject'' > > at the end of the file to inject the has_active_xxx methods to > ActiveRecord. AThis helps very much. Thank you. My thinking regarding implementation of this leans towards the AR::BASE injection technique you outline above. It has the following attractions for me: 1. The code is kept in a readily identifiable file. 2. The implementation details are invisible to coders working with the models; mainly, if not solely, me ;-). What would you favour? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I take it that the module file in lib would need to be explicitly loaded in config/enviorinment.rb or somewhere similar, correct? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 7 May 2008, at 14:21, James Byrne wrote:> > I take it that the module file in lib would need to be explicitly > loaded > in config/enviorinment.rb or somewhere similar, correct?You''d probably do that in config/initializers these days Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi -- On Wed, 7 May 2008, James Byrne wrote:> > I take it that the module file in lib would need to be explicitly loaded > in config/enviorinment.rb or somewhere similar, correct?It depends how it''s used. First of all, if you''re require''ing things in environment.rb, they should probably be in config/initializers, which is where (as of Rails 2.0) you put things that are one-time, application-specific loads to be loaded when the server starts. If your library doesn''t fall into that category, then lib is a likely choice. If, however, it''s a non-ActiveRecord model, then app/models is the place. I know I''m generalizing past your case, but bear with me as it might be helpful. Rails has a mechanism for resolving unknown constants. If you refer to, say, MyConstant, Rails will look in its load-path for a file called my_constant.rb, and will load it. The assumption is that MyConstant will be defined in my_constant.rb. If it isn''t, you get an error message. (Likewise if my_constant.rb doesn''t exist, though a different error message: unknown constant.) If your constant is MyClass::MyConstant, Rails will look for my_class/my_constant.rb somewhere in the load path. All of this means that if you use this mechanism, naming your file appropriately and letting Rails automatically load it the first time you use the name of your class or module, you don''t have to load it explicitly. By the way, here''s a nice demo of the constant-resolving mechanism, which Rails also uses for its own purposes. I have a model class called Container, in models/container.rb. $ ./script/console Loading development environment (Rails 2.0.2)>> Object.constants.grep(/Container/)=> [] # No matching constants.>> Container # I refer to Container;# this prompts Rails to # go load the model file # in an attempt to resolve # the constant, which succeeds. => Container(id: integer, name: string, created_at: datetime, updated_at: datetime)>> Object.constants.grep(/Container/) # And here it is.=> ["Container"] David -- Rails training from David A. Black and Ruby Power and Light: INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin INTRO TO RAILS June 24-27 London (Skills Matter) See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
David A. Black wrote:> > I know I''m generalizing past your case, but bear with me as it might > be helpful.Sad to say perhaps, but my ignorance is so vast I that I am grateful for every snippet of information that I can fit into my existing understanding. Your help is greatly appreciated. I tried out something similar in console which, in its own way, is equally illuminating. $ ruby script/console Loading development environment (Rails 2.0.2)>> ApplicationLoadError: Expected ./app/controllers/application.rb to define Application The module I am contemplating will probably have a "terminate", "terminate_row" or perhaps "deactivate_row" method to set the superseded_after attribute as well as setting the active_row attribute to contain the sql code that passes through :conditions. There may be other related helper methods that belong in there as well. Given that there likely will be more than one method I will probably put the resulting file (active_row.rb ?) into config/initializers. I learned a lot from this. Many thanks. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> David A. Black wrote: > >> >> I know I''m generalizing past your case, but bear with me as it might >> be helpful. > > Sad to say perhaps, but my ignorance is so vast I that I am grateful for > every snippet of information that I can fit into my existing > understanding. Your help is greatly appreciated.This applies to everyone, especially Fred and Andy, lest the context imply otherwise. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---