Remove render controller prefix on Rails

Attention! This article assumes you have at least a basic understanding of Ruby on Rails

In Ruby on Rails there is a good convention with partials. If you have a controller named BooksController and on the view (we call view but it is a template), when you call the partial /books/_article.html.erb inside the views folder will be used. This is not so good if I have a controller inside the namespace of other controller. Let’s say CheckoutController in /library/checkout_controller.rb and I want to use a partial called _side_status.html.erb that is on the shared folder,it will get the path:

To fix this we can set config.action_view.prefix_partial_path_with_controller_namespace to false on config/application.rb, but this would affect every call to render on the application.
A better way to do this is to build a helper method that takes care of this on specific calls to partials.

Here is one way to do it, you can put this inside ApplicationHelper or create any other helper of your choice:

def render_without_prefix(path, options = {})
  old_value = ActionView::Base.prefix_partial_path_with_controller_namespace

  ActionView::Base.prefix_partial_path_with_controller_namespace = false
  render(path, options)
  ActionView::Base.prefix_partial_path_with_controller_namespace = old_value

and make some tests

describe '#render_without_prefix' do
  subject { helper.render_without_prefix partial }

  let(:partial) { 'presenters/nil_partial' }
  let(:options) { {} }

  it 'renders the partial with :prefix_partial_path_with_controller_namespace of ActionView set to false' do
    expect(ActionView::Base).to receive(:prefix_partial_path_with_controller_namespace=).with(false).ordered
    expect(helper).to receive(:render).with(partial, options).ordered.and_call_original
    expect(ActionView::Base).to receive(:prefix_partial_path_with_controller_namespace=).with(true).ordered

    expect(subject).to eq('')

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s