Partial isn't working - ruby-on-rails

I'm new to rails and I'm following the first tutorial on api.rubyonrails.org.
However, I've finished the entire tutorial except for a specific problem I've skipped.
The following partial isn't working:
<%= render :partial => 'comments/comment',
:collection => #post.comments %>
For some reason, it throws the following error:
Missing partial comments/comment with
{:handlers=>[:erb, :builder], :formats=>[:html], :locale=>[:en, :en]}. Searched in:
* "c:/rails/blog/app/views"
I don't quite understand what the purpose of :collection is(perhaps someone could elaborate).
You can find see the files on my github repo below:
http://github.com/imjp/blog

You simply misspelled the name of the partial:
_comment.html.errb
instead of:
_comment.html.erb
For the explanation of collection see here: http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
Para 3.4.5

Related

Why does a Missing Partial error occur occasionally when the file exists?

While running Cucumber tests, from time to time it will fail intermittently. The error is:
*** ActionView::Template::Error Exception: Missing partial items/_fields with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml]}. Searched in:
* "/my/path/to/application/app/views"
* "/my/path/to/rvm/gems/ruby-2.1.5/gems/kaminari-0.16.3/app/views"
* "/my/path/to/rvm/gems/ruby-2.1.5/gems/devise-3.5.4/app/views"
Yes, the partial file does exist in /my/path/to/application/app/views/items/_fields.html.haml
The kicker is that sometimes the test will pass, other times it will fail. I am running on a Red Hat 5 machine.
So to debug this, I decided to throw in a begin/rescue.
.fields
- begin
= render partial: 'items/fields', locals: {f: f}
- rescue Exception => e
= byebug
- if f.can_modify?(:object_a)
= render partial: 'layouts/object_a_field', locals: {f: f, field: :object_a}
- else
.field#object_a
= render partial: 'layouts/attribute', locals: {label: 'Object A', value: f.object.object_a_id ? f.object.object_a_number : 'Not Assigned'}
.field#name
- if f.can_modify?(:name)
= f.label :name
= f.text_field :name, {class: 'inputbox large_field', readonly: f.cannot_modify?(:name)}
.smltxt (short description of the item)
- else
= render partial: 'layouts/attribute', object: f.object, locals: {field: :name}
For those curious what's in the partial items/fields:
.field
- if f.can_modify?(:name)
= f.label :name, 'Item'
= f.text_field :name, {class: 'inputbox uppercase', maxlength: 16, readonly: !f.object.identifier.new_record?}
.smltxt (character identifier)
- else
= render partial: 'layouts/attribute', object: f.object, locals: {field: :name, label: 'Item'}
When it passes, I obviously don't hit the byebug, but when it fails, I do! Which allows me to play with it in a Rails Console type environment.
So I decided to run that specific command:
(byebug) render partial: 'items/fields', locals: {f: f}
And I get:
*** ActionView::Template::Error Exception: Missing partial items/_fields with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml]}. Searched in:
* "/my/path/to/application/app/views"
* "/my/path/to/rvm/gems/ruby-2.1.5/gems/kaminari-0.16.3/app/views"
* "/my/path/to/rvm/gems/ruby-2.1.5/gems/devise-3.5.4/app/views"
So I thought I'd remove the locals to see if anything changed:
(byebug) render partial: 'items/fields'
And I get:
*** ActionView::Template::Error Exception: undefined local variable or method `f' for #<#<Class:0x0000002a907610>:0x00000027beae48>
So obviously it's now magically finding the partial, and it knows that it is missing a local variable f.
Update 1
I added the rest of the view that is calling the partial above for clarity.
In an attempt to troubleshoot, I also took the contents of items/_fields.html.haml and placed it where I had the render partial: 'items/fields', locals: {f: f}... then the test passed, which means that the other partials in the file didn't have an issue either. So it doesn't seem like it could be related to the content of the file.
Update 2
It seems by adding the #javascript tag to our very first Cucumber feature often fixes this issue. Somehow having the browser loaded before the other tests, improves the chances of it passing. Makes no sense to me, maybe someone else has an idea about this?
Update 3
It has been discovered today that the error is not related to Cucumber at all. The same error was found in production. The web interface showed a Missing Partial error, but for a file that did indeed exist. After restarting the Passenger server with touch tmp/restart.txt and then the error went away. So it's still very intermittent.
Update 4
I added the content of the partial that seems to be missing randomly.
How would I go about discovering why Rails cannot find a partial that is actually there?
This error usually happens when the format of the request is different and there is no template that can respond to it example format.js, format.html etc. The request will only work if the template items/_fields.html.haml is a it will only be correct if the request format is html
I think you can rename your file to items/_fields.haml if you want to use to respond it any request format.
I had a similar issue but with another gem for handlebars. It is usually because of caching.
Try in your cucumber setup setting
ActionView::Base.cache_template_loading = false
If the above works you DO have a caching issue that will occur on production.
There is an open issue for caching not being enabled in dev mode here: https://github.com/indirect/haml-rails/search?utf8=%E2%9C%93&q=cache_template_loading
I strongly believe upgrading to Ruby 2.3.1 solved this for us. I am not certain what may have changed. When we were investigating this, my colleague and I thought we found a line in the Rails source code that was rendering partials differently based on the Ruby version.
I'm having trouble finding that now, but I still wanted to post that the problems seems to have vanished ever since we upgraded to a newer Ruby.
I think you could try specifying the format and handler of the partial you're rendering:
= render(
partial: 'items/fields',
formats: [:html],
handlers: [:haml],
locals: {f: f}
)
The most commonly used content types in Rails are :js, :json, and :html. If you are using Rails UJS, you can specify the content type in the link or form elements. An example would look like this:
<%= form_for #task, remote: true, data: {'type' => :json} %>
...
In our controller, we will respond accordingly:
def create
respond_to do |format|
format.json { render json: { status: 200, html: render_to_string(partial: 'form') }.to_json }
end
end
Now if your form partial looks like this:
tasks/_form.html.erb
Rails will raise an ActionView::Template::Error Exception: Missing partial. You specified the content type to be json, so it was searching for:
tasks/_form.json.erb
Now if you changed the form to:
<%= form_for #task, remote: true, data: {'type' => :html} %>
...
And controller like this:
def create
respond_to do |format|
format.html { render text: { status: 200, html: render_to_string(partial: 'form') } }
end
end
You can even render json in html content type response:
def create
respond_to do |format|
format.html { render json: { status: 200, html: render_to_string(partial: 'form') }.to_json }
end
end
And then in javascript:
JSON.parse(data);
The above scenerio would work fine because it will be searching for an html file extension in the call to render. That's the important part. The call to render is what raises the error. When you use render, you must make sure you have a template or partial that matches the content type.
One solution mentioned above is to remove the extension. But unless you are responding to multiple formats, it seems a bit overkill. My recommended solution is to look at what the error message is telling you it expects. In your case it was expecting html:
:formats=>[:html]
Try accessing the file from your terminal to see whether it's available or not.
If you can't find it from the terminal, go to your app folder in your text editor and delete it manually.
After that, use the terminal to create it again.
It appears the file is not readable even though it is visible in your text editor, but not visible when accessing it from the terminal.
For some weird reason, this works.
Note: Same applies to folders

Rails is Looking for a Partial in the Wrong Directory

I have a polymorphic Review model. The namespaced model User::Library::Publication is reviewable. The reviews are created properly, but when I try to display them through a partial, Rails looks up the wrong directory.
In my view:
<%= render #review %>
I get this error:
Missing partial user/library/reviews/review with {:locale=>[:en], :formats=>[:js, :html], :handlers=>[:erb, :builder]}
Rails is apparently looking for the review partial within the namespace's directory views/user/library instead of the /views/reviews. Any idea why this is happening?
If you want to remove namespacing from the partial template path, you can set the prefix_partial_path_with_controller_namespace variable in your config/application.rb:
# config/application.rb
config.action_view.prefix_partial_path_with_controller_namespace = false
This will load partial paths as you define them (without the namespace).
You can see the original Pull Request here.
If you use name spaces you have to create folders/sub folders so Rails is not looking at the wrong place.
If you want to force the partial path just use:
render :partial => "review"
And create rename the review.html.erb file to _review.html.erb

Missing template for render user/new

I have a problem when trying to render a controller action. Following the documentation I should be able to use:
render 'user/new' or
render template: 'user/new' or
render :action => "new", :controller => "users"
Although I get a template missing exception and I'm not shure, why. Using a form for works, but it's stupid to copy exactly the same form.
I'm pretty messed, so I'm shurely missing something, but I don't get it.
Any hints?
EDIT: I'm calling from the GroupsController where I want to render the new-user-form. Did a test with only scaffolded models and I get the same error.
ActionView::Template::Error (
Missing partial users/new with {:locale=>[:de], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in:
* "/Users/rob/Development/projects/test/app/views"
* "/Users/rob/.rvm/gems/ruby-1.9.3-p362/gems/oembed_provider_engine-0.2.0/app/views"
* "/Users/rob/.rvm/gems/ruby-1.9.3-p362/gems/devise-2.2.3/app/views"
):
Partial templates' filename always begins with an underscore. So you need a "_new.html.erb" file in your "user" view to render.
If I'm not mistaken, the default scaffolding creates a "_form.html.erb" for each model to render it in new and edit actions both. You can just render that instead of the whole "new" view.

Missing partial when using devise 2.0 w Rails 3.1.3

I have a rails app (rails 3.1.3) that has a shopping cart model. I wanted to show a summary of the shopping cart in the layout so I created the partial views/carts/_cart.html.haml. My app was working fine and rendering the cart partial in every view. But when I installed devise 2.0, the partial could no longer be found for devise views. Instead, I would see the following error code when I tried to call a devise view:
ActionView::Template::Error (Missing partial views/carts/cart with {:handlers=>[:erb, :builder, :coffee, :haml], :formats=>[:html], :locale=>[:en, :en]}. Searched in:
* "/Users/cameronnorgate/Web Development/Practice Apps/1-Camerons Tea/pgktea/app/views"
* "/Users/cameronnorgate/.rvm/gems/ruby-1.9.2-p290#pgktea/gems/devise-2.0.4/app/views"
As you can see, it searches for the partial in app/views, but doesn't go all the way into the 'carts' folder in order to find the 'cart' partial. This is weird, because the code I had in the layout view specified the exact path (see below):
%body{:class => params[:controller]}
.master_container
.master_header
.inner_header
.cart
= render :partial => 'views/carts/cart', :object => #cart
Can anyone help me understand why my call to render the partial is not being found when inside a devise view?
The short term fix I've made for this is to bring the partial code back into the full layout file - so now devise doesn't have to go searching and everything works... but that's not ideal and it's cluttering up my code.
Thanks!
You should be able to specify the partial with just:
= render :partial => 'carts/cart', :object => #cart
The views/ part of your definition is probably throwing it off. app/views is implied, so when you specify views/carts/cart, it's probably not finding a views directory under app/views.
If this page can be access from other pages . then
= render :partial => '/carts/cart', :object => #cart
Is the correct way , because if this page open in other models then 'carts/cart' will not be available like if url is ex. 'localhost:3000/products' this page will give missing partial error so / will solve the issue and as other answers, 'views' is not needed

rails 3 rendering a partial from a collection

I am trying to render a partial on a collection with <%= render #posts %> which returns the error:
Missing partial posts/post with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}
However it works if i use <%= render :partial => 'post', :collection => #posts %>
I have _post.html.erb in the same folder which uses post variable (from posts)
Why would the former example way of rendering a partial on a collection not work, but the latter example does work?
EDIT: I should specify I'm using Rails 3.2.1
The default of to_partial_path for your objects is always scoped under a view folder for the class, so your partial must be in the posts view folder.
When you use the form render :partial => 'post' it looks in the folder of the controller you are currently under.
I suspect that you are not working in the PostsController view folder, which would explain the behavior you are seeing. If you are working in the posts view folder, then something else must be going on so if you could provide more detail that would help diagnose it further

Resources