It looks to me as if controllers/application.rb is only accessible from controllers and helpers/*.rb is only accessible from templates. So, neither one is accessible from a model. Am I missing something? Basically, I want to know where to put methods that can be used by any of several models and what I need to do to access them. It has been suggested that I put the methods into files in lib/, but I''m not sure how to access them (from there) in my model code. -r -- email: rdm-go8te9J4rpw@public.gmane.org; phone: +1 650-873-7841 http://www.cfcl.com - Canta Forda Computer Laboratory http://www.cfcl.com/Meta - The FreeBSD Browser, Meta Project, etc.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Sep 19, 2005, at 3:42 PM, Rich Morin wrote:> Basically, I want to know where to put methods that can be used by > any of several models and what I need to do to access them. It has > been suggested that I put the methods into files in lib/, but I''m > not sure how to access them (from there) in my model code.app/models/common_behavior.rb module CommonBehavior def foobar; end end app/models/some_model.rb require_dependency ''common_behavior'' class SomeModel < ActiveRecord::Base include CommonBehavior end app/models/another_model.rb require_dependency ''common_behavior'' class AnotherModel < ActiveRecord::Base include CommonBehavior end Now both classes have the foobar instance method. Note that I put everything modeling my domain in the models dir, not just persistence classes. Regards, jeremy -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (Darwin) iD8DBQFDL0FsAQHALep9HFYRAsvhAKDEfMKGPubPSX61RkK6KhI0VKnrpgCgkKGV WLudrBYUDOKtA3GAZleVxK4=G/im -----END PGP SIGNATURE-----
OK, I got pointed to http://wiki.rubyonrails.com/rails/show/ExtendingActiveRecordExample http://wiki.rubyonrails.com/rails/show/UnderstandingWhatMethodsGoesWhere which appear to address this general problem. Now I''m hassling with the specifics (sigh). -r -- email: rdm-go8te9J4rpw@public.gmane.org; phone: +1 650-873-7841 http://www.cfcl.com - Canta Forda Computer Laboratory http://www.cfcl.com/Meta - The FreeBSD Browser, Meta Project, etc.
On 9/19/05, Rich Morin <rdm-go8te9J4rpw@public.gmane.org> wrote:> It looks to me as if controllers/application.rb is only accessible > from controllers and helpers/*.rb is only accessible from templates. > So, neither one is accessible from a model. Am I missing something? > > Basically, I want to know where to put methods that can be used by > any of several models and what I need to do to access them. It has > been suggested that I put the methods into files in lib/, but I''m > not sure how to access them (from there) in my model code.This can be done through a mixin (which is what a helper is basically..) # lib/my_module_mixin.rb module MyModelMixin def xoo ''xoo is new'' end end # app/models/foo.rb class Foo < ActiveRecord::Base include MyModelMixin end # usage @foo.zoo # => ''xoo is new'' Now, let''s say you want to add a class method: # lib/my_module_mixin.rb module MyModelMixin def self.included(base) base.extend(ClassMethods) end def xoo ''xoo is new'' end module ClassMethods def bar ''bar'' end end end # usage Foo.bar # => ''bar''
Still missing something. I have the following code in place:
lib/edge_list.rb
----------------
module Edge_list
# self.neighbors - find neighbors for a file_node, etc.
def self.neighbors
...
end
end
models/file_node.rb
-------------------
class FileNode < ActiveRecord::Base
require ''edge_list''
include Edge_list
# This should probably be somewhere else...
def self.neighbors_x
...
end
end
views/admin/show.rhtml
----------------------
...
<% for edge in FileNode.neighbors %>
<%= sprintf("%d -(%d)-> %d\n",
edge.src_id, edge.edge_desc_id, edge.dst_id)
%>
<% end %>
...
If I try the code in this form, it gets a nastygram:
undefined method `neighbors'' for FileNode:Class
If I change "for edge in FileNode.neighbors" to
"for edge in FileNode.neighbors_x" in
views/admin/show.rhtml,
it works just fine. Wazzup?
-r
--
email: rdm-go8te9J4rpw@public.gmane.org; phone: +1 650-873-7841
http://www.cfcl.com - Canta Forda Computer Laboratory
http://www.cfcl.com/Meta - The FreeBSD Browser, Meta Project, etc.
OK, I tried Jeremy Kemper''s suggestion, but it''s still failing
for me.
Is there some magic that''s needed to get show.rhtml to "see"
methods
which have been include''d into file_node.rb? Here''s what I
have now:
models/edge_list.rb
------------------
module EdgeList
# self.neighbors - find neighbors for a file_node, etc.
def self.neighbors
...
end
end
models/file_node.rb
-------------------
require_dependency ''edge_list''
class FileNode < ActiveRecord::Base
include EdgeList
# This should probably be somewhere else...
def self.neighbors_x
...
end
end
views/admin/show.rhtml
----------------------
...
<% for edge in FileNode.neighbors %>
<%= sprintf("%d -(%d)-> %d\n",
edge.src_id, edge.edge_desc_id, edge.dst_id)
%>
<% end %>
...
--
email: rdm-go8te9J4rpw@public.gmane.org; phone: +1 650-873-7841
http://www.cfcl.com - Canta Forda Computer Laboratory
http://www.cfcl.com/Meta - The FreeBSD Browser, Meta Project, etc.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Sep 19, 2005, at 4:37 PM, Rich Morin wrote:> OK, I tried Jeremy Kemper''s suggestion, but it''s still failing for me. > Is there some magic that''s needed to get show.rhtml to "see" methods > which have been include''d into file_node.rb? Here''s what I have now:module SomeModule def self.a_class_method; end def an_instance_method; end end class Foo include SomeModule end This includes the *instance methods* defined in SomeModule in Foo. a_class_method is a method of the SomeModule module itself and is not pulled into Foo. Here''s a common idiom for including both instance and class methods: module SomeModule # When you do "class Foo; include SomeModule; end" # Ruby calls SomeModule.included(Foo) if it''s defined. def self.included(base_class) # Call super to get the normal behavior of pulling in the # instance methods. super # Now extend the class itself with our class methods. base_class.extend ClassMethods end module ClassMethods def a_class_method # ... end end def an_instance_method end end Now "class Foo; include SomeModule; end" pulls in both class and instance methods: Foo.a_class_method, Foo.new.an_instance_method. For further study, check out the Pickaxe book. This is more Ruby than Rails territory. jeremy -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (Darwin) iD8DBQFDL1Q3AQHALep9HFYRAvuhAKCM2OpZ9KC60eKIyFyivmQa5mJz+wCgvKMg mLdU6ZS1vX639l71hxnCupY=2UID -----END PGP SIGNATURE-----
On 9/19/05, Rich Morin <rdm-go8te9J4rpw@public.gmane.org> wrote:> > OK, I tried Jeremy Kemper''s suggestion, but it''s still failing for me. > Is there some magic that''s needed to get show.rhtml to "see" methods > which have been include''d into file_node.rb? Here''s what I have now:<snip/> Try this: In conig/environment.rb: require ''edge_list'' ActiveRecord::Base.class_eval do include Edge_list end Josh _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Following Jeremy Kemper''s advice, I read up a bit on class and instance methods (using Rails to learn Ruby is not without peril :-). It turns out that I didn''t really NEED a class method, so I was able to simplify things quite a bit. -r -- email: rdm-go8te9J4rpw@public.gmane.org; phone: +1 650-873-7841 http://www.cfcl.com - Canta Forda Computer Laboratory http://www.cfcl.com/Meta - The FreeBSD Browser, Meta Project, etc.