3. Using Components

First, there is render_component within the view. This is implemented just like any other view helper and returns a string which is, generally, displayed inline within the calling view. An example of it’s use might look like <%= render_component(:controller => 'image', :action => 'recent_image') %>.

This will probably be the most common invocation.

Secondly, there is render_component within the controller. This has the effect of passing both control flow and view rendering off to the component being called. This is useful if you have a controller that implements logic to determine what should be displayed but would prefer to utilize code already in a component method to handle the rest of the logic once it’s determined what is needed to be done. It allows for your code to be more DRY (don’t repeat yourself). This will probably be the least used invocation.

Finally, there is render_component_as_string (just added a few minutes ago). This works like the render_component available to the view, but can be used in the controller. This is useful if your application has a feature like a “sidebar builder” that allows the user to select what information they would like displayed in the sidebar. The controller can then call each component in succession, creating a string with the returned data to be provided to the view. Or, to be even more componenty (is that a word?.. it is now), the view could call a component of the SideBarBuilderController called “build_sidebar”, that would then gather the needed information using render_component_as_string and then would use render_text to provide the final output of all the components together. I imagine this will be the second most highly used invocation.

Rails’ components offer one final feature. For those of you interested in being as modular as possible, there is the components directory (found one level below app). This directory is meant to hold other directories which contain entire subsets of functionality: controllers, models, and views. The allows the components to exist entirely outside of the standard app directory and makes for simple tar/untar style distribution and installation.

Use of it is quite simple. An example will work best. Let’s assume we’d like our Image functionality mentioned above to be a self-contained component. In our components directory, we’d create a directory called gallery. We’d place our model (image.rb) and our controller (image_controller.rb) inside the gallery directory. Inside of gallery we’d create a directory to hold the views, we’ll call it image.

From this point forward, your models, views, and controllers should be coded just as they would be normally, with three exceptions.

First, the controller must call the uses_component_template_root method in it’s class definition. This informs Rails that the views for this controller will be located in the components directory and NOT in the usual location.

Secondly, your controller and model must reference the fact that it is now a member of a Ruby Module named Gallery (the capitalized version of the name of the directory we created under components). For example, our ImageController should now be started as class Gallery::ImageController < ActionController. The same change needs to take place in the model code.

Finally, when referencing this controller (say, in a render_component call) we’ll need to include the directory name. As an example, to call our recent_image method in the controller from a view we would use the following: <%= render_component(:controller => 'gallery/image', :action => 'recent_image') %>.

This allows the most modularity and encourages code to be divided into components the introduce specific functionality, unbound to any other component.