Forum: Rails-core (closed, excessive spam) hacking rails core classes

Posted by ara howard (Guest)
on 2008-05-23 17:14
(Received via mailing list)
i think this has come up before, but i can't seem to find any
references and googling isn't turning up much.

i have a set of modifications i've made to rails core classes which i
find very useful, there are only a few, which i have in 'lib/
railsext.rb', shown here

   http://pastie.caboo.se/202230

now i currently use

   load 'railsext.rb'

in app/controller/application.rb to merge these hacks into the rails
core classes.  i've found this is needed because of the way rails does
reloading on each request - in otherwords some classes aren't fully
baked until the code hits the ApplicationController.

now this works well, but it fails for

   ./script/console

in some respects.

my question is: if i'm hacking rails core classes like this is there a
place i can do it, physically or logically, that will apply the hacks
correctly regardless of whether the code is being loaded in a
development request loop, from ./script/console, or however?

hopefully this question makes sense.

kind regards.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama
Posted by Jan De Poorter (Guest)
on 2008-05-23 17:19
(Received via mailing list)
Dear Ara,

Although this really is a question for rails-talk, not rails-core,
I'll just answer it here

If you want something loaded in your application that falls beyond the
scope of default Rails stuff (for example your Core ext) you should
load it in your environment.rb file. Just put it at the bottom.
Or you can move the library from lib/ to config/initializers if you're
running Rails Edge / 2.1RC

Regards,
Jan De Poorter
Posted by ara.t.howard (Guest)
on 2008-05-23 17:50
(Received via mailing list)
On May 23, 2008, at 9:18 AM, Jan De Poorter wrote:

>
> Regards,
> Jan De Poorter

no that won't work, which is my whole point.  loading code like that
in environment.rb can cause issues because the classes get torn-down/
built-up on the request loop.  i've had issues with this before and
had to read the source carefully to determine what can and cannot be
done but i'm hacking an older rails app (1.2.3) and didn't want to go
through that again.  i know this question has come with respect to
plugins as well and it's not simply the case that you can hack
ActionController, ActiveRecord, or other rails classes at any point
and have it work in all cases.

regards.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama
Posted by ara.t.howard (Guest)
on 2008-05-23 17:56
(Received via mailing list)
On May 23, 2008, at 9:18 AM, Jan De Poorter wrote:

> If you want something loaded in your application that falls beyond the
> scope of default Rails stuff (for example your Core ext) you should
> load it in your environment.rb file. Just put it at the bottom.
> Or you can move the library from lib/ to config/initializers if you're
> running Rails Edge / 2.1RC

just realized i could have been more specific:

if you put

class ApplicationController < ActionController::Base
   hacks
end

in lib/railsext and load that from environment.rb, and initializer, or
a plugin, rails will fail to load ApplicationController in the request
loop since it's not undefined and thus the const_missing code doesn't
come into play.  so the concrete issue is hacking
ApplicationController in a modular way - in otherwords without dumping
code into app/controllers/application.rb and avoiding hacking
ActionController::Base itself (to avoid littering).

regards.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama
Posted by Jan De Poorter (Guest)
on 2008-05-23 18:04
(Received via mailing list)
Maybe I'm missing something here, but as far as I know this gets
solved in plugins with Class#include

You define your methods in a module, which you the include in
ApplicationController. That way const_missing gets called and
ApplicationController code gets loaded.

ApplicationController.send(:include, MyApplicationControllerHacks)
Posted by ara.t.howard (Guest)
on 2008-05-23 18:08
(Received via mailing list)
On May 23, 2008, at 10:03 AM, Jan De Poorter wrote:

> Maybe I'm missing something here, but as far as I know this gets
> solved in plugins with Class#include
>
> You define your methods in a module, which you the include in
> ApplicationController. That way const_missing gets called and
> ApplicationController code gets loaded.
>
> ApplicationController.send(:include, MyApplicationControllerHacks)

yup, and using ApplicationController.module_eval in a lib/* file has a
similar effect.  what i'm asking is what is the preferred/canonical
method outside of plugins.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama
Posted by ara.t.howard (Guest)
on 2008-05-23 18:14
(Received via mailing list)
On May 23, 2008, at 10:03 AM, Jan De Poorter wrote:

> Maybe I'm missing something here, but as far as I know this gets
> solved in plugins with Class#include
>
> You define your methods in a module, which you the include in
> ApplicationController. That way const_missing gets called and
> ApplicationController code gets loaded.
>
> ApplicationController.send(:include, MyApplicationControllerHacks)

just confirmed that the above will not work, at least not with ancient
rails (1.2.3.).  placing the single line

   ApplicationController.send :include, Module.new

in my lib/railsext.rb causes rails to blow up with

opt/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/
active_support/dependencies.rb:422:in `remove_const': cannot remove
Object::VERSION_MAJOR (NameError)
         from /opt/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/
lib/active_support/dependencies.rb:422:in `send'
         from /opt/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/
lib/active_support/dependencies.rb:422:in `remove_constant'
         from /opt/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/
lib/active_support/dependencies.rb:368:in `new_constants_in'
         from /opt/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/
lib/active_support/dependencies.rb:368:in `each'
         from /opt/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/
lib/active_support/dependencies.rb:368:in `new_constants_in'
         from /opt/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/
lib/active_support/dependencies.rb:495:in `require'
         from /opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.3/bin/../
lib/mongrel/rails.rb:147:in `rails'
         from /opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.3/bin/
mongrel_rails:113:in `cloaker_'
          ... 19 levels...
         from /opt/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/
commands/server.rb:39
         from /opt/local/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:27:in `gem_original_require'
         from /opt/local/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:27:in `require'
         from ./script/server:3


on boot.


it's not that simple to hack ApplicationController, at least in older
rails.

a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama
Posted by Jeff Cohen (jeff)
on 2008-05-23 21:03
(Received via mailing list)
On May 23, 11:13 am, "ara.t.howard" <ara.t.how...@gmail.com> wrote:
> On May 23, 2008, at 10:03 AM, Jan De Poorter wrote:
> it's not that simple to hack ApplicationController, at least in older  
> rails.
>

Perhaps this might help? http://errtheblog.com/posts/4-autopatch-rails

Jeff
Posted by Michael Koziarski (Guest)
on 2008-05-24 08:24
(Received via mailing list)
> it's not that simple to hack ApplicationController, at least in older
> rails.

Why are you munging ApplicationController?  It's part of the
application so it'll get reloaded every request in dev mode, and it's
something you have control over.  Basically you have two options:

1) Monkeypatch into ActionController::Base in a plugin / initializer

AC::Base isn't reloaded, so you'll be fine.

2) simply reference your module in ApplicationController's definition:

class ApplicationController < ActionController::Base
  include InternetDrama
end

Either of those should work fine.


--
Cheers

Koz
Posted by ara.t.howard (Guest)
on 2008-05-24 08:32
(Received via mailing list)
On May 24, 2008, at 12:24 AM, Michael Koziarski wrote:

> Why are you munging ApplicationController?  It's part of the
> application so it'll get reloaded every request in dev mode, and it's
> something you have control over.


simply because i want to both isolate and re-use the code.  for this
lib/railshacks.rb is preferable.

>  Basically you have two options:
>
> 1) Monkeypatch into ActionController::Base in a plugin / initializer
>
> AC::Base isn't reloaded, so you'll be fine.

cool - this the route i ended up taking.

>
>
> 2) simply reference your module in ApplicationController's definition:
>
> class ApplicationController < ActionController::Base
>  include InternetDrama
> end
>
> Either of those should work fine.


won't use that since the point is you have a single file for all my
rails hacks and simple require it to put into effect, but that's nice.

thanks a bunch.


a @ http://codeforpeople.com/
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama
This topic is locked and can not be replied to.