Rendering a Partial from another Folder - ruby-on-rails

I'm Trying to render a Partial from my App/view/pins folder to my
app/view/layout folder (My menu).
Basically i'm trying to render my _form.html.erb to a Modal which is
triggered with a button on my Menu.
I'm using Bootstrap.
Every time i give my modal the code:
<%= render 'pins/form' %>
i'm getting:
NoMethodError in Pins#index
undefined method `model_name' for NilClass:Class
I searched A LOT and EVERYWHERE but couldn't fix it..
Can anybody Help me?
(Git repo-> https://github.com/Theminijohn/Amphitryon)
Errors:
The Error Trace -> http://i.imgur.com/i4aVQNd.png

Try using this:
<%= render :partial => 'pins/form' %>
Edit
I looked at your code. In your pins/form partial you're referring to #pin instance variable, which may not be available in your partial. That's why your stack trace is referring to a NilClass.
I think you can try to pass #pin as a local partial variable in one of these ways:
<%= render :partial => 'pins/form', :locals => { :pin => #pin } %>
or (shorthand syntax)
<%= render "pins/form", :pin => #pin %>

Try replacing #pins in the simple form definition with current_user.pins.new

The shorthand render #pins is doing this:
render :partial => 'pin', :collection => #pins
whereby each pin is passed as a local variable.
However, your partial references the instance variable #pin which, unless explicitly assigned in the controller, will return nil:
<%= simple_form_for(#pin, #...snipped...
Change it to the local variable, like so:
<%= simple_form_for(pin, #...snipped...

How i Fixed it
Thank you for all your Help, without you guys i wouldn't have figured it out.
1.) I Changed the form from #pin to
current_user.pins.new
2.) Than, because the modal got rendered without the user being logged in and that caused an error i wrapped the modal in an if statement
<% if user_signed_in? %>
...form code...
<% end %>
and everything worked perfectly.

Related

undefined method `each' for nil:NilClass while attempting to use a partial

I'm currently having the issue for when I try to use a partial inside of invoices/_form.html.erb, it goes into parts/_index.html.erb and breaks.
Inside of the parts_controller I have:
def _index
#parts = Part.all
end
#unsure if this is needed
Inside of invoices_controller I have:`
def new
#invoice = Invoice.new
#parts = Part.all
end`
Inside of invoices/_form.html.erb I have:
<%= render :partial => "parts/index" , :part => #parts %>
And inside of invoices/new.html.erb I have:
<h1 style="padding-left:120px">New Invoice</h1>
<%= render 'form', invoice: #invoice, part: #parts %>
<%= link_to 'Back', invoices_path, class: "btn btn-default col-md-2" %>
So what this code is attempting to do is display the index page of parts so the user is able to see all current parts they have in stock, and how many of that part is in stock. The parts/index page is the exact same as the the default index page for parts, but it just has a link removed.
The line of code that gives me an issue in parts/index is:
<% #parts.each do |part| %>
And what's confusing me about that is that I should be passing it an object that has data inside of it, since it's declared in both the controller for parts, and the invoice controller. Am I missing something super simple with my syntax, or is what I'm trying to do not the right way to do it? I'm still a noob to rails, so sorry if what I'm trying to get across doesn't make too much sense.
so here is the problem:
<%= render :partial => "parts/index" , :part => #parts %>
you are sending :part to your _index.html.erb partial while using #parts
you need to update your render call to following:
<%= render :partial => "parts/index" , locals: {parts: #parts}%>
and your loop to:
<% parts.each do |part| %>
you provide to _index.html.erb variable part but try to render #parts.
1. you don't need method _index, when your patial _index.html.erb render that not get variable #parts from method _index. I think it's wrong.
2. You need to render in _index.html.erb variable which it's provided from _form
<% part.each do |part_| %>

NoMethodError while rendering a partial

I have a welcome.html.erb page with welcome_controller. On this page I try to render a partial which belongs to Screen model, but it returns NoMethodError: undefined method 'each' for nil:NilClass. Here's the code:
welcome.html.erb:
<%= render 'screens/all` %>
_all.html.erb:
<%= #screens.each do |screen| %>
<%= link_to screen do %>
<img src="">
<% end %>
<% end %>
screens_controller.rb:
def all
#screens = Screen.all.order('created_at ASC')
end
Hey you are doing wrong.
def all
#screens = Screen.all.order('created_at ASC')
end
That method you have in screens_controller.rb
You need to write the instance inside the welcome method at welcome_controller.rb, That way it will not give error to you.
That way you can access the partial and one more thing pass the variable in locals with partial and use that instead of the actual instance.
<%= render :partial =>'screens/all`, :locals => {:screens => #screens} %>
The instance variable you're using (#screens) should be coming from whatever controller action renders welcome.html.erb. You should then pass it explicitly as a local (like Bharat shows in his answer).
you Forgot to pass the variable
Try using
<%= render 'screens/all',:screens => #screens %>

Rendering action

I'm trying to render an action in my application.html.erb layout file to display it as a modal box using some jquery scripts. I've heard that i can use render :template => 'spots/new' but it looks like this method is not rendering an action but just a view file.
spots#new
def new
#spot = Spot.new
end
new.html.erb
<%= form_for(#spot) do |f| %>
...
<% end %>
The problem is that when i'm trying to render spots#new with render :template => 'spots/new', i'm getting undefined method 'model_name' for NilClass:Class error. Have you any idea what am i doing wrong ? Thanks in advance
You are correct, render :template => 'spots/new' just renders your view template, it does not call spots#new. You should create #spot instance variable before rendering the template.
In your case probably following code will work:
<% #spot ||= Spot.new %>
<%= form_for(#spot) do |f| %>
...
<% end %>

Is there any Rails function to check if a partial exists?

When I render a partial which does not exists, I get an Exception. I'd like to check if a partial exists before rendering it and in case it doesn't exist, I'll render something else. I did the following code in my .erb file, but I think there should be a better way to do this:
<% begin %>
<%= render :partial => "#{dynamic_partial}" %>
<% rescue ActionView::MissingTemplate %>
Can't show this data!
<% end %>
Currently, I'm using the following in my Rails 3/3.1 projects:
lookup_context.find_all('posts/_form').any?
The advantage over other solutions I've seen is that this will look in all view paths instead of just your rails root. This is important to me as I have a lot of rails engines.
This also works in Rails 4.
I was struggling with this too. This is the method I ended up using:
<%= render :partial => "#{dynamic_partial}" rescue nil %>
Basically, if the partial doesn't exist, do nothing. Did you want to print something if the partial is missing, though?
Edit 1: Oh, I fail at reading comprehension. You did say that you wanted to render something else. In that case, how about this?
<%= render :partial => "#{dynamic_partial}" rescue render :partial => 'partial_that_actually_exists' %>
or
<%= render :partial => "#{dynamic_partial}" rescue "Can't show this data!" %>
Edit 2:
Alternative: Checking for existence of the partial file:
<%= render :partial => "#{dynamic_partial}" if File.exists?(Rails.root.join("app", "views", params[:controller], "_#{dynamic_partial}.html.erb")) %>
From inside a view, template_exists? works, but the calling convention doesn't work with the single partial name string, instead it takes template_exists?(name, prefix, partial)
To check for partial on path:
app/views/posts/_form.html.slim
Use:
lookup_context.template_exists?("form", "posts", true)
In Rails 3.2.13, if you're in a controller, you can use this :
template_exists?("#{dynamic_partial}", _prefixes, true)
template_exists? is delegated to lookupcontext, as you can see in AbstractController::ViewPaths
_prefixes gives the context of the controller's inheritance chain.
true because you're looking for a partial (you can omit this argument if you want a regular template).
http://api.rubyonrails.org/classes/ActionView/LookupContext/ViewPaths.html#method-i-template_exists-3F
I know this has been answered and is a million years old, but here's how i ended up fixing this for me...
Rails 4.2
First, i put this in my application_helper.rb
def render_if_exists(path_to_partial)
render path_to_partial if lookup_context.find_all(path_to_partial,[],true).any?
end
and now instead of calling
<%= render "#{dynamic_path}" if lookup_context.find_all("#{dynamic_path}",[],true).any? %>
i just call <%= render_if_exists "#{dynamic_path}" %>
hope that helps. (haven't tried in rails3)
I have used this paradigm on many occasions with great success:
<%=
begin
render partial: "#{dynamic_partial}"
rescue ActionView::MissingTemplate
# handle the specific case of the partial being missing
rescue
# handle any other exception raised while rendering the partial
end
%>
The benefit of the code above is that we can handle tow specific cases:
The partial is indeed missing
The partial exists, but it threw an error for some reason
If we just use the code <%= render :partial => "#{dynamic_partial}" rescue nil %> or some derivative, the partial may exist but raise an exception which will be silently eaten and become a source of pain to debug.
What about your own helper:
def render_if_exists(path, *args)
render path, *args
rescue ActionView::MissingTemplate
nil
end
This works for me in Rails 6.1:
<% if lookup_context.exists?("override_partial", ['path/after/app/views'], true) %>
<%= render partial: "path/after/app/views/override_partial" %>
<% else %>
<%= render partial: "default_partial" %>
<% end %>
Here I have my partial nested some levels deeper than normal (app/views/path/after/app/views/_override_partial) so that's why I'm adding it as the prefixes array, but you can use lookup_context.prefixes instead if you don't need it.
I could have also used prepend_view_path on the controller. It's up to you :)

Problem rendering partial in the application layout (Rails)

Here's the call in the application.html.erb file:
<%= render :partial => 'tasks/_new' %>
Here's the partial being rendered (_new.html.erb):
<% form_for #task do |f| -%>
<%= f.text_field :body %>
<%= submit_tag "Submit" %>
<% end -%>
Here's the method in the 'tasks' controller:
def new
#task = Task.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #task }
end
end
Here's the error message I keep getting:
Missing template tasks/__new.erb in view path app/views
And it says the error is in this line:
<%= link_to "tasks", tasks_path %> <%= render :partial => 'tasks/_new' %>
The file is in the right directory. The weird thing is that there's an
extra _ in the file name, in the error. When I give in and rename the
partial to __new.erb, here's the error I get:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
And it says the error is in this line:
<% form_for #task do |f| -%>
I had also tried without the _ in the code, as Petros suggested, but it returns the same error as above, Called id for nil….
What's going on?
You don't need the _ in your code. It should be:
<%= render :partial => 'tasks/new' %>
The first error is because you don't need to put the _ inside the :partial parameter. Rails takes care of that. That's why you get double __ because Rails will put one for you.
The second error is your real problem. The error suggests that #task is nil. This is true because the partial only knows what the container view knows, and your view in that particular moment hasn't called the action from the proper controller. As you (Baby Diego) already found out and indicated in one of your comments below, you needed to create an instance of a Task in your partial. I don't know if there is a more elegant solution, but maybe someone can suggest something better in the future.
Thanks to MattMcKnight for informing us that the partial itself does only know what the container view knows.
Petros correctly identified the first issue- you don't need the underscore in the partial call.
The second thing to know about partials is that they don't call the controller method, they just reference the view. Thus, you need to setup the #task object in every action that uses that partial, or just call Task.new in the partial. When I have a partial in a layout in similar situations, I usually load it with JavaScript so that I can call the action.
If the partial needs to know about a variable in the calling erb file, you can pass it like this:
<%= render partial: "tasks/new", locals: { task: #task } %>
And in file app/views/tasks/_new.html.erb, refer to the variable like this:
<% form_for task do |f| %>
<%= f.text_field :body %>
<%= submit_tag "Submit" %>
<% end %>
That is, without the #. (The code a: b is just a more convenient form of :a => b.)
I wonder, though, why do you want to use partials in file application.html.erb? I'm assuming that you mean the Ruby-generated file app/views/layouts/application.html.erb, which is supposed to be used as a layout file containing elements common to all your application's pages, not for business logic. Perhaps the file you need to call the partial from is app/views/tasks/index.html.erb?

Resources