Run script after initialize

hi there!!

I’m just trying to run a script that adds certain methods (with
different name) to all
activerecord models, but what happens is that it seems that
all models are loaded after the application runs.

ActiveRecord::Base.send(:descendants).each do |subclass|
#do stuff
end

ActiveRecord::Base.send(:descendants) and
ActiveRecord::Base.send(:subclasses) is allways empty [].

I’ve tried it on config/environment.rb and config/application.rb with no
success, can someone tell me what i can do about it?

Thanks!

On 6 May 2012, at 20:22, Guillem V. [email protected] wrote:

ActiveRecord::Base.send(:descendants) and
ActiveRecord::Base.send(:subclasses) is allways empty [].

I’ve tried it on config/environment.rb and config/application.rb with no
success, can someone tell me what i can do about it?

You could just reopen ActiveRecord::Base. Create a new initializer (a
ruby file in config/initializers) with:

class ActiveRecord::Base
def new_method
# do stuff
end
end

Does that help?
Jeremy W.
http://www.ihid.co.uk

Jeremy W. wrote in post #1059748:

On 6 May 2012, at 20:22, Guillem V. [email protected] wrote:

ActiveRecord::Base.send(:descendants) and
ActiveRecord::Base.send(:subclasses) is allways empty [].

I’ve tried it on config/environment.rb and config/application.rb with no
success, can someone tell me what i can do about it?

You could just reopen ActiveRecord::Base. Create a new initializer (a
ruby file in config/initializers) with:

class ActiveRecord::Base
def new_method
# do stuff
end
end

Does that help?
Jeremy W.
http://www.ihid.co.uk

Not in my case. What I want to do is define different method names
depending on its relation, for example:

ActiveRecord::Base.send(:descendants).each do |subclass|
subclass.reflect_on_all_associations.each do |association|
macro = association.macro #:has_one, :has_many…
subclass.send(:define_method, “#{association.name}_tokens”) do
read_attribute(method[0…-8])
end
end
end

Guillem V. wrote in post #1059754:

Jeremy W. wrote in post #1059748:

On 6 May 2012, at 20:22, Guillem V. [email protected] wrote:

ActiveRecord::Base.send(:descendants) and
ActiveRecord::Base.send(:subclasses) is allways empty [].

I’ve tried it on config/environment.rb and config/application.rb with no
success, can someone tell me what i can do about it?

tryied something different, but no success again:

Dir[Rails.root.join(‘app/models/*.rb’).to_s].each do |filename|
require filename #Connection not stablished…
klass =
File.basename(filename).sub(/.rb$/,‘’).classify.safe_constantize
next klass.ancestors.include?(ActiveRecord::Base)
klass.reflect_on_all_associations.each do |association|
klass.send(:define_method, “#{association.name.to_s}_tokens”) do
read_attribute(method)
end
end
end

It raises connection not stablished.

On 6 May 2012 22:13, Guillem V. [email protected] wrote:

You could just reopen ActiveRecord::Base. Create a new initializer (a
http://www.ihid.co.uk
end
end

OK, so two more suggestions:

  1. Use an after_initialize block in your config (
    Configuring Rails Applications — Ruby on Rails Guides)
    to call your method_creation code.
  2. Re-open the class (as per my prev suggestion) but write a
    create_association_tokens method that contains the code to define your
    reflected methods, and use ActiveRecord::Base’s after_initialize method
    to
    call that method on an object, thus creating your methods on an
    object-by-object basis, rather than for the class.

I’m intrigued by the point of all this?

Well, I’d create a file and put it in /lib and include/initialize that
file in the config.ru file before the actual app initialization (run
YourApp::Application).

Jeremy W. wrote in post #1059759:

On 6 May 2012 22:13, Guillem V. [email protected] wrote:

You could just reopen ActiveRecord::Base. Create a new initializer (a
http://www.ihid.co.uk
end
end

OK, so two more suggestions:

  1. Use an after_initialize block in your config (
    Configuring Rails Applications — Ruby on Rails Guides)
    to call your method_creation code.
  2. Re-open the class (as per my prev suggestion) but write a
    create_association_tokens method that contains the code to define your
    reflected methods, and use ActiveRecord::Base’s after_initialize method
    to
    call that method on an object, thus creating your methods on an
    object-by-object basis, rather than for the class.

I’m intrigued by the point of all this?

Sorry about the delay, I couldn’t access to a computer since now :(.

Done it, but it raises me an error because i have a attr_writer, i need
to initialize the method.

module MyModule
def self.included(base)
base.send(:extend, InstanceMethods)
base.send(:after_initialize, :set_reader_writer_tokens)
end

module InstanceMethods
def set_reader_writer_tokens
class.reflect_on_all_associations.each do |association|
self.class.send(:define_method,
“#{association.name.to_s}_tokens=”) do |value|
write_attribute(method, self.another_custom_method)
end
#more stuff
end
end
end
end

ActiveRecord::Base.send(:include, MyModule)

Loading development environment (Rails 3.2.2)
class OptionType < ActiveRecord::Base
belongs_to :type
end

OptionType.new(:type_tokens => “ba,b”)
raises an unknown attribute :type_tokens.

But if I first initialize the record withouth accessing to the
attribute:

OptionType.new
=> #<OptionType …>
OptionType.new(:type_tokens => “ba,b”)
=> #<OptionType id: nil, name: nil, presentation: nil, created_at: nil,
updated_at: nil>

Then I can done it. The problem is that I need to set up that attribute
before the initialitzation of the class.

Is a very good approach, but still not enogh for a ruby on rails
application.

Maybe it can be done using method_missing… but I’m a little bit scared
of overwriting activerecord method_missing, also it’s not clear.

If the config.ru trick doesn’t work for you, you should try the same but
only initializing the file in config/boot.rb, instead. This should work
for sure.

Sent from my iPod

Rodrigo V. wrote in post #1059873:

Well, I’d create a file and put it in /lib and include/initialize that
file in the config.ru file before the actual app initialization (run
YourApp::Application).

That worked! The problem is that this is only working when rails app
starts, not on rake tasks or test/units.

But from now on, what I need for my application is ok.

Just to know… Is it possible to do add those methods on the entire
application? (not only on the middleware)