Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm starting Rails and Ruby for a short time. But I try to make it the cleanest way I can. So, in an attempt to clean my view I try to custom my FormBuilder. Like this :

# /config/initializers/custom_form_builder.rb    
class ActionView::Helpers::FormBuilder

  # My test form function
  def test label
    return "Whatever I want to do ..."
  end
end

And then I can use it like this :

# /app/views/test/test.html.erb
...
<%= form_for test, :html => {:multipart => true} do |f| %>
  ...
  <%= f.test(":-)") %>
  ...
<% end %>
...

This part works perfectly fine.

However, what I want to do know is to create form views containing the HTML code I want to use in my forms. This way, I can store the HTML of all my form in a pseudo-HTML way, and structured within my directories.

So I created a template :

# /app/views/forms/test.html.erb
<input type="text" value="test" />

And I tried to render it from my FormBuilder :

# /config/initializers/custom_form_builder.rb
def test label
  render "forms/test"
end

And I added it to my routes :

# /config/routes.rb
match "/forms/test"    => "forms#test"

So my questions lies here :

  1. Do I try to make it work the wrong way ?
  2. Is it possible to render from my FormBuilder Class ?
  3. Is there some useless code in there ?

Thanks in advance,

John

share|improve this question

2 Answers

I made it a different way. But, the answer was quite simple.

The class ActionView::Helpers::FormBuilder inherit of the @template attribute.

And to render my partials, I just need to call it this way :

def test label
  @template.render "/forms/test"
end

Then you can use the partial as specified on RoR Guides

share|improve this answer

For anybody interested, I made some change in the way to put the WHOLE FormBuilder Customization in the VIEW part (app/views/_forms/).

# /app/helpers/application_helper.rb
module ApplicationHelper
  # We set the custom_form_for function to call form_for with with the CustomFormBuilder builder.
  def custom_form_for(name, *args, &block)
    # We get every hash option from args
    options = args.extract_options!

    # We call form_for with the defined builder.
    form_for(name, *(args << options.merge(:builder => CustomFormBuilder)), &block)
  end
end

# /app/helpers/custom_form_builder.rb
# Allow you to custom forms from templates
class CustomFormBuilder < ActionView::Helpers::FormBuilder
  # Customed forms list
  @custom_forms = []

  def self.create_tagged_field(method_name)
    # Define the function for the corresponding template
    define_method(method_name) do |label, *args_list|
      # Define the template name to be used
      template_name = "/_forms/#{method_name}"

      args = args_list.size > 1 ? args_list : args_list.first

      # Render the partial template with the corresponding object and args. 
      @template.render :partial => template_name, :locals => { :label => label, :params => args, :item => object }
    end
  end

  # Get the list of set partial templates in app/views/_forms
  @custom_forms = Dir['app/views/_forms/_*.html.erb'].map{|file| file.gsub(/^.*[\\\/]_/, "").gsub(/\.html\.erb$/, "") }

  # Create the tagged field function for every defined templates
  @custom_forms.each do |name|
    create_tagged_field(name)
  end
end

This way, I get the whole Custom FormBuilder during the server start. You just have to put your partials in the /app/views/_forms/ directory.

Exemple :

/app/views/MyPersonalTemplate.html.erb

<% custom_form_for dish do |f| %>
<%= f.submit "My custom save label !!" %>
<% end %>

/app/views/_forms/_submit

<input type="submit" value="<%= label %>" name="commit">

Thank you to give be your advise and feeling about the form customization.

Especially if you think it useless or if there already has some useful libs to do it !

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.