aceofbassgreg
aceofbassgreg

Reputation: 3947

Dynamic rendering of partials in Rails 3

In the app I'm working on, I have defined a method task_types in the model:

task.rb
  def self.task_types
["ad_hoc"]
  end

I use task_types to populate a drop-down menu, but I would also like to use it to dynamically render a partial.

What I have in mind is, for each task type, there will be an associated comment box. I went ahead and made a helper that will call the correct partial depending upon which task type was selected:

#tasks_helper.rb
module TasksHelper

  def completion_comment(task)
    task_types = @task.task_type
    render :partial => "#{Task.task_types}", :locals => {:task => task}
  end
end

Unfortunately, when I called completion_comment, I received the error message "The partial name (["ad_hoc"]) is not a valid Ruby identifier."

What I'm looking for is a dynamic way to render the appropriate partial. I think I'm on the right track, but I'm not sure how to extract the array elements from my task_types method (as you can see in the error message, the brackets and quotation marks are getting pulled into the render action). Or, perhaps I need to utilize a different method for dynamically rendering the partial. Any help is appreciated.

Upvotes: 2

Views: 4519

Answers (3)

aceofbassgreg
aceofbassgreg

Reputation: 3947

Here's what worked:

module TasksHelper

  def render_task_form(task)
    render :partial => "/tasks/completed/#{task.task_type.downcase}"
  end
end

I had tried this solution much earlier, and had received an error that "The partial name (/tasks/completed/) is not a valid Ruby identifier; make sure your partial name starts with a letter or underscore, and is followed by any combinations of letters, numbers, or underscores."

I tried it again, and to remedy this problem I deleted all tasks from the database. Now the partial renders dynamically. Hopefully this helps someone else!

Upvotes: 2

Gautam Rege
Gautam Rege

Reputation: 697

In Rails 4, the view or the partial name is supposed to respond to a valid Ruby identifier. So, the entire view name must follow the same format as a ruby-identifier:

  • it should start with a _ or character
  • it cannot start with a number
  • it can have only _ and alphanumerics.

So, considering that task_type is a valid ruby identifier (which it should be), it will work. In generate this code will not work in Rails 4

render '/tasks/completed/some-task' 

but this will work

render '/tasks/completed/some_task'  # note the underscore.

Upvotes: 0

nbrew
nbrew

Reputation: 781

You need a string instead of the entire task_types array. @task.task_type should return a key that a) matches an element in the task types array and b) matches a known partial.

The following is a bit more complicated that it needs to be but should do the trick:

tasks_helper.rb
module TasksHelper

  def completion_comment(task)
    if Task.task_types.include? task.task_type
      render  :partial => task.task_type,
              :locals => {
                :task => task
              }
    else
      # render a generic comment box here
    end
  end
end

Upvotes: 0

Related Questions