views:

33

answers:

3

I am modifying a Ruby Rails application - Redmine. I want to modify a function that renders a partial preview. In the view I believe this is accomplished via

<%= render :partial => 'documents/form' %>

I need to modify the function this is attached to.

Where might I look for this? Is render the function I am looking for? Is :partial a parameter? What does the => operator do?

I do realize learning Ruby and Rails would solve these issues, but for the current situation I just need to know enough to make a small tweak. I know it's not in the controller.

+1  A: 

You're looking for render method in ActionController::Base class. It takes hash of options as parameter. (BTW, if you can't recognize ruby hash when you see one, maybe it's a bit early for you to "tweak" rails. You can always go through some Ruby tutorial first)

As you know, monkeypatching is very, very bad, blah-blah-blah, now go and shoot yourself in the foot :)

  class ActionController::Base
    def render
      # Now I'm in charge of rendering!
    end
  end
Nikita Rybak
I wonder if he's looking to override the view helper though, not through ActionController?
Andrew Vit
+1  A: 

It might help to know what kind of tweak you're trying to do. Modifying a core function like render is most likely not a good idea, and there's certainly a much easier way.

By overriding this, you'll affect every other place where render is used. Why not create your own render method as a helper?

# app/helpers/application_helper.rb
module ApplicationHelper
  def render_my_crazy_thing
    return "stuff you want to see: " + render(:partial => 'documents/form')
  end
end

The ActionView#render method handles all different cases of rendering, switching on different parameters: partials, collections of objects, etc. The :partial => 'documents/form' parameter is the ruby syntax for a hash (key => value).

Andrew Vit
"app/helpers" helpers are accessible in views only, not in controllers. Controller helps you usually put in app/controllers/application_controller.rb
Nikita Rybak
Yes, but his example shows ERB... no sense clobbering the controller's render method too!
Andrew Vit
@Andrew You're right, my bad!
Nikita Rybak
+3  A: 

I'm assuming that you would like to change the code for the partial itself, and just want to know where to find the template for that partial, not change the render method, which is part of Rails itself, as some of the other answers have suggested.

The render method tells Rails to render a particular template, possibly with some parameters passed in. A partial is a kind of template that is intended to render only a fragment of a page, such as an individual widget or a single section of the page. The syntax render :partial => "documents/form" is Ruby's way of passing keyword arguments to method; it is essentially just saying to render documents/form as a partial template. (In Ruby, this is actually equivalent to render({:partial => "documents/form"}), which is just invoking method render, passing in a hash table in which :partial, a keyword, maps to "documents/form", a string).

So, the code that will actually be rendered is the partial documents/forms. By convention, partials are loaded from files prefixed with _; and if you're using the default ERb template format, then they will likely end in .html.erb. As all view code is stored in app/views, you will probably be looking for app/view/documents/_form.html.erb. Yes, this is a not particularly obvious bit of convention, but that's Rails for you.

See the Rails Guide on partials and rendering for more information.

Brian Campbell
This is the most sane answer... I do hope Josh actually meant "edit the template" rather than "modify a function" as he wrote.
Andrew Vit
This is close to what I was looking for. The application involved WYSIWYG editor CKeditor in Redmine, but for some of the "partial" descriptions of a couple pages in Redmine were rendering full HTML so text using h1, h2, etc. was getting rendered ridiculously large in the descriptions below titles. I ended up editing the view to strip HTML tags for the display on the pages involved. Your assumptions were correct.
Josh