[Constant Reloading] Where is the right place to put MyCustomFormBuilder?

19 views
Skip to first unread message

Andrey Nering

unread,
Jan 15, 2015, 6:51:39 AM1/15/15
to rubyonra...@googlegroups.com
I have a custom form builder for my application:

# file location: /lib/ruby/app_form_builder.rb

class ActionView::Helpers::AppFormBuilder < ActionView::Helpers::FormBuilder
  include
ActionView::Helpers::TagHelper
  include
ActionView::Context

 
def foo
   
'bar'
 
end
end


I am requiring it in an initializer:

require "#{Rails.root}/lib/ruby/app_form_builder.rb"
ActionView::Base.default_form_builder = ActionView::Helpers::AppFormBuilder


This works, but I have to restart the server on every change. I was reading the Constant Guide, but didn't find the right way to made this file to be automaticaly reloaded. I tried to put this in /app/helpers forlder and making it default in application.rb, but I got "unitialized constant" error.

Also, I would like to know if Rails can reload code that modify native Ruby classes:

class String
 
def do_something
   
'something'
 
end
end




Frederick Cheung

unread,
Jan 15, 2015, 7:28:32 AM1/15/15
to rubyonra...@googlegroups.com

On Thursday, January 15, 2015 at 11:51:39 AM UTC, Andrey Nering wrote:
I have a custom form builder for my application:
I am requiring it in an initializer:

require "#{Rails.root}/lib/ruby/app_form_builder.rb"
ActionView::Base.default_form_builder = ActionView::Helpers::AppFormBuilder


This works, but I have to restart the server on every change. I was reading the Constant Guide, but didn't find the right way to made this file to be automaticaly reloaded. I tried to put this in /app/helpers forlder and making it default in application.rb, but I got "unitialized constant" error.


require is never a good idea if you want something to be reloaded. You've also got a clash between the class name and it's location on disk - having the class just be AppFormBuilder in lib/app_form_builder.rb should work.

Lastly if you look into the bowels of action view, the default_form_builder method looks like this

 def default_form_builder
     builder = ActionView::Base.default_form_builder
     builder.respond_to?(:constantize) ? builder.constantize : builder
 end

So if you set default_form_builder to be a "AppFormBuilder" then that should allow it to be reloaded.
 
Also, I would like to know if Rails can reload code that modify native Ruby classes:

class String
 
def do_something
   
'something'
 
end
end



This can't be done. code reloading is done by removing the class/module (using remove_const) and then letting it be loaded again, which wouldn't work for a class like String

Fred

Andrey Nering

unread,
Jan 15, 2015, 12:47:12 PM1/15/15
to rubyonra...@googlegroups.com
I couldn't make this work with "default_form_builder" method.

My solution was using a custom "form_for" method:

# application_helper.rb

def app_form_for(object, options = {})
  options
.merge!(builder: AppFormBuilder)
  form_for
object, options do |f|
   
yield f
 
end
end


And adding the Builder folder on autoload_paths.

@Frederick Cheung: Thank you for your help!
Reply all
Reply to author
Forward
0 new messages