Hi, I would like to factor the following code out of my Product model so that I can mix it into any model. Since the code depends on other models a plugin would not be stand alone. I have tried to make a module in a separate file in app/models/ and require it to include, extend Product but nothing I have tried works. Any suggestions how I can get the has_many statement and my method_missing method out of Product? They work perfectly in Product but I can''t share them with other models this way. Thanks! Peter class Product < ActiveRecord::Base has_many :virtual_attribute_values, :foreign_key => ''owner_id'', :conditions => "owner_class = ''#{self.to_s}''", :dependent => true def method_missing(method_id, *args, &block) end end _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Francois Beausoleil
2005-Nov-21 01:28 UTC
Re: Factoring code out of a model but not as a plugin
2005/11/20, Peter Michaux <petermichaux@gmail.com>:> I would like to factor the following code out of my Product model so that I > can mix it into any model. Since the code depends on other models a plugin > would not be stand alone. I have tried to make a module in a separate file > in app/models/ and require it to include, extend Product but nothing I have > tried works. Any suggestions how I can get the has_many statement and my > method_missing method out of Product? They work perfectly in Product but I > can't share them with other models this way.# lib/virtual_attributes.rb module VirtualAttributes has_many :virtual_attribute_values, :foreign_key => 'owner_id', :conditions => "owner_class = '#{self.to_s}'", :dependent => true def method_missing(method_id, *args, &block) end end # app/models/product.rb class Product < ActiveRecord::Base include VirtualAttributes end WARNING: Untested, but should be along those lines. Please be warned that you MUST call method_missing because the ActiveRecord::Base framework relies on method_missing by itself. So, if you can't find the attribute, just super away. Bye ! -- François Beausoleil http://blog.teksol.info/ _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Hi Francois, I tried what you said but it doesn''t work. When I use @ product.test_virtual_attribute in a view Rails uses ActiveRecord''s method_missing instead of mine. (My method_missing does include a "super" call.) It is like my module is not getting included. If I move my method_missing back into Product and only leave the has_many statement in the module then I get an error like "virtual_attribute_values unknown method or attribute". Again, it looks like my module is not getting included. I''m stumped. Any ideas? Peter _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Francois Beausoleil
2005-Nov-21 02:41 UTC
Re: Factoring code out of a model but not as a plugin
2005/11/20, Peter Michaux <petermichaux@gmail.com>:> If I move my method_missing back into Product and only leave the has_many > statement in the module then I get an error like "virtual_attribute_values > unknown method or attribute". Again, it looks like my module is not getting > included. > > I'm stumped. > > Any ideas?Try to require the virtual attr library at the end of environment.rb. At least worth a try. Also, in the file, put a logging statement near the start and end, just to verify that the file is indeed loaded. A simple $stderr.puts or RAILS_DEFAULT_LOGGER.warn is enough. Good luck ! -- François Beausoleil http://blog.teksol.info/ _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
I tried all these things and still no luck. I don''t see anything in development.log indicating RAILS_DEFAULT_LOGGER.warn I also tried putting a line of garbage in the module asdfsdaf.sadfsadfasdf and that didn''t cause an error. Scratching my head. Peter _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Hi Peter, your problem is similar to one one of mine, so I''m also hoping for some help on this :) I want to override the [] and []= methods in any ActiveRecord::Base descendants that I choose, by mixing in module "RosterAccess". For example, class Chessboard < ActiveRecord::Base include RosterAccess end board = Chessboard.new board[1,1] = Queen.new(:white) However my overridden []= method never gets called. ActiveRecord''s implementation gets called instead, and that doesnt make the Queen happy :p cheers Gerret On 11/21/05, Peter Michaux <petermichaux-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi Francois, > > I tried what you said but it doesn''t work. When I use > @product.test_virtual_attribute in a view Rails uses ActiveRecord''s > method_missing instead of mine. (My method_missing does include a "super" > call.) It is like my module is not getting included. > > If I move my method_missing back into Product and only leave the has_many > statement in the module then I get an error like "virtual_attribute_values > unknown method or attribute". Again, it looks like my module is not getting > included. > > I''m stumped. > > Any ideas? > > Peter > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > >
I tried this and got the obviously expected error I was hoping for. All of this is in product.rb module Asdf asdfasdf.asdffsad end class Product < ActiveRecord::Base include Asdf end So either Rails is not making the factored out module''s file visible to Product or Ruby is not complaining when it cannot find this file? -Peter _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Peter Michaux <petermichaux@...> writes:> > I tried this and got the obviously expected error I was hoping for. All ofthis is in product.rb> module Asdf > asdfasdf.asdffsad > end > class Product < ActiveRecord::Base > include Asdf > end > So either Rails is not making the factored out module''s file visible to > Product or Ruby is not complaining when it cannot find this file? > -Peter > > _______________________________________________ > Rails mailing list > Rails@... > http://lists.rubyonrails.org/mailman/listinfo/rails >In your case peter, because you want to add virtual ''fields''/attribute, overriding read_attribute and write_attribute might work just as well. If you look as ActsAsI18n, this is what I do as well. I''ve boiled it down to the basics below. In particular note that the original read/write_attribute methods are aliased and that the new methods intercept, check if they should be called and then fallback to the original methods. If you don''t have a list of field names, then you may want to check for the original methods raising an exception, then catch with your implementation instead. By overwriting the read/write_attribute methods, you handle all methods of accessing the attributes (via the method missing which calls these methods, via []/[]= and via read/write). ----- require ''active_support'' require ''active_record'' module ActiveRecord #:nodoc: module Acts #:nodoc: module I18n def self.append_features(base) super base.extend(ClassMethods) end module ClassMethods def acts_as_i18n(options = {}) ## this prevents acts_as_i18n from being called multiple times return if self.included_modules.include?(ActiveRecord::Acts::I18n::InstanceMethods) ## finally, add instance and singleton methods class_eval do alias_method :i18n_orig_read_attribute, :read_attribute alias_method :i18n_orig_write_attribute, :write_attribute include ActiveRecord::Acts::I18n::InstanceMethods end end end module InstanceMethods def i18n_get_field(f); end def read_attribute(attr) if self.class.i18n_fields.include?(attr.to_sym) return i18n_get_field else return i18n_orig_read_attribute(attr) end end def i18n_set_field(f,v); end def write_attribute(attr,val) if self.class.i18n_fields.include?(attr.to_sym) return i18n_set_field(attr,val) else return i18n_orig_write_attribute(attr,val) end end end end end end
Problem solved. It was a matter of restarting WEBrick so it would see the changes in lib/ files. Seems like all is working well now. I guess it is part of how WEBrick works but if I make changes outside of the app/ directory they are not noticed unless I restart WEBrick. This is a bit of a pain when developing (tweaking CSS, for example). Any way to make development life with WEBrick a little easier? Thanks, Peter _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails