I'm having a problem rendering a JSON partial with JBuilder (version ~>2.0) on Rails 4.2. It's giving me the ActionView missing partial error despite the file existing, it appears to be ignoring the path I provide and searching the default magic path. I realise that putting the partial at the magic path would fix it, but for a number of reasons it would be preferable to keep the partial where it is and find it correctly. The partial is being found correctly from elsewhere in my /views directory structure (specifically from /views/api/task_templates/_task_template.json.jbuilder
).
Main JBuilder file, which is itself a partial (_task_template.json.jbuilder):
json.task_files task_template.task_files.each do |file|
json.partial! file, partial: 'api/task_files/task_file', as: :task_file
end
Partial file (_task_file.json.jbuilder):
json.(task_file, :id, :file_type, :name, :original_path, :image_path, :icon, :organization_id, :viewer)
Error message:
ActionView::Template::Error:
Missing partial api/v1/task_files/_task_file with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:jbuilder]}. Searched in:
* "/Users/lucy/trail-app/app/views"
* "/Users/lucy/.rvm/gems/ruby-2.1.3@trail-app/gems/sidekiq_monitor-0.1.7/app/views"
* "/Users/lucy/.rvm/gems/ruby-2.1.3@trail-app/gems/devise_invitable-1.7.0/app/views"
* "/Users/lucy/.rvm/gems/ruby-2.1.3@trail-app/gems/devise-4.2.0/app/views"
And this is my directory structure:
/views > /api > /task_files > _task_file.json.jbuilder (THE MISSING PARTIAL)
> /v1 > /task_templates > _task_template.json.jbuilder (THE MAIN FILE)
I finally found the answer to this in the depths of the Ruby documentation while looking for something completely different, so I am recording it here for anyone that might come looking for an answer.
Don't even bother giving the partial option in the JBuilder file. Add a method, to the class you are making a partial of, called to_partial_path
. That method should return a string of the path to the partial you want.
For example, in my case:
Main JBuilder file:
json.task_files task_template.task_files.each do |file|
json.partial! file, as: :task_file
end
In the TaskFile model (task_file.rb):
class TaskFile
def to_partial_path
'api/task_files/task_file'
end
end
And the partial file remains the same. That works.