2

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.

5
  • Maybe a symbol instead if a string works? Try :ad_hoc instead of "ad_hoc". Or is it important to have a string object? ... Oh I see: I think the problem is the Array... :-/ Commented Mar 7, 2013 at 22:22
  • Same problem (The partial name ([:ad_hoc]) is not a valid Ruby identifier)...I wonder if there's a method I can call in my task_types definition, or if it's something I have to do when I'm trying to render the partial. Commented Mar 7, 2013 at 22:25
  • Array can not be accepted as partial name. Commented Mar 7, 2013 at 22:30
  • @ValeryKvon - Yes, that's the problem I'm having...I want to pass the elements of the array, not the array itself, but I'm unsure as to how I should proceed. If I have to revamp my whole approach, that's fine. Commented Mar 7, 2013 at 22:32
  • What do you mean: pass the elements of the array, like what? Commented Mar 7, 2013 at 22:33

3 Answers 3

2

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!

Sign up to request clarification or add additional context in comments.

Comments

0

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

1 Comment

Thanks for your help. The code you provided was still giving me the entire array, but I was able to figure out a solution that worked.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.