Rails render partial from controller - ruby-on-rails

I'm trying to render different partials into my index view from the controller, depending on the params I receive.
I have a simple unless-else condition inside my controller that checks the params
def index
unless params[:check].nil?
render :partial => /layout/check
else
render :partial => /layout/not_check
end
end
And I have the files _check.html.erb and not_check.html.erb into the folder layout/
Now, how can I show that partials inside my index view?
At the moment I can just visualize the partial alone as a single view, but not inside the requested view.

The better way would be to call the partials from index.html.erb
<% unless params[:check].nil? %>
<%= render :partial => '/layout/check' %>
<% else %>
<%= render :partial => '/layout/not_check' %>
<% end %>
so your def index would look like this
def index
respond_to do |format|
format.html
end
end
I did not understand what you are trying to do but partial which are related to controller/actions should not be in layout unless they are serving some layout.

If you're trying to render a layout (and not actual view information) try using render layout
def index
if params[:check].nil?
render layout: "not_check"
else
render layout: "check"
end
end

Related

Rails - Can I Show Different Partials in a View After an Error?

I have a Rails 5 app that has a view that shows different forms based on params. The correct form is shown when the view first shows
However, when there's an error, it always shows the same partial.
diary_controller
def edit
#view = params[:view]
end
def update
respond_to do |format|
if #diary.update(diary_params)
format.html { redirect_to #diary, notice: 'Diary was successfully updated.' }
format.json { render :show, status: :ok, location: #diary }
else
format.html { render :edit }
format.json { render json: #diary.errors, status: :unprocessable_entity }
end
end
end
edit.html.erb
<% if #view == 'close' %>
<%= render 'close_fields'%>
<% elsif #view == 'new'%>
<%= render 'new_fields' %>
<% else %>
<%= render 'all_fields' %>
<% end %>
Currently, it always shows the 'all_fields' partial when there's an error.
Is it possible to show the partial originally shown while retaining the data the user entered in the fields, along with the error messages (currently shown under the text field because I use simple_form)?
------------UPDATE------------
When I add puts params[:view] in :edit, it returns close in the console.
When I add puts params[:view] in :update, it returns nothing in the console. I also tried putting #view = "close" in update. When I did this, the correct view was shown after an error.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"f7JoOucLkUlOyt31NW9HaJIWyXKVSu7q91kspfZYjgdF3hJneRKapnCPtgJn+R5NOC5nDhNvkB8PzzHNs9aLkg==", "diary"=>{"last_date"=>"", "notes"=>"hi, hi!", "update_type"=>"close", "view"=>"close"}, "reason_list_select2"=>"going on vacation", "season_reason_list_select2"=>"", "temp_reason_list_select2"=>"", "area"=>[{"id"=>"4", "action"=>"Not Applicable"}], "commit"=>"Close Diary", "id"=>"27"}
In your update action, you never set #view and so it is always nil in which case your if... elsif... else statement always resolves to <%= render 'all_fields' %>.
If you want your if statement in edit.html.erb to resolve to something other than else, then set your #view variable in your update action.
Based on the update to your question, the problem is now that :view is nested inside :diary:
"diary"=>{"last_date"=>"", "notes"=>"hi, hi!", "update_type"=>"close", "view"=>"close"}
So, you need to do #view = params[:diary][:view] instead of #view = params[:view].
In your diary_controller
before_action :load_view, only: [:edit, :update]
# Your action methods here
private
def load_view
#view = params[:view]
end
And make sure in all your forms (close_fields, new_fields, all_fields), you have a hidden filed named view which value is set to #view.
Once try like this in your
edit.html.erb
<% if #view.to_s == 'close' %>
<%= render :partial => 'close_fields'%>
<% elsif #view.to_s == 'new'%>
<%= render :partial => 'new_fields' %>
<% else %>
<%= render :partial =>'all_fields' %>
<% end %>
Note :your partial file name should have an underscore like this: _all_fields.html.erb

How to access related models in RoR after using link_to?

I use wkhtmltopdf to convert a page to pdf
<%= link_to "download" user_group_assessments_path(#user, #group, #assessment, format: 'pdf') =>
It will go to my AssessmentsController and call my index method, it looks like:
#assessments = Assessment.all
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
end
end
end
In show.pdf.erb I access user, group and assessment.
Every thing is ok and it works without any problem. But when I call
<% #assessment.measurements.each do |m| %>
...
<% end %>
I get the following error:
Undefined method 'measurements' for nil:NilClass
And it points to the line where I am trying to access measurement.
How can I access the model 'measurement' from this file?
You need to send your assessment details to your view. for example:
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
locals: {:assessment => #assesment}
end
end
Then in your view assessment can be accessed as
<% assessment.measurements.each do |m| %>
...
<% end %>
In controller your variable is #assessments but for iteration you are trying to use #assessment which is missing plural s. Try as following
<% #assessments.each do |assessment| %>
<% assessment.measurements.each do |m| %>
...
<% end %>
<% end %>
Or, you must need an #assessment instance variable in your controller action. and then you can use following loop
<% #assessment.measurements.each do |m| %>
...
<% end %>
Try to this if you have an association with measurements
#assessments = Assessments.joins(:measurements)
and in your view do this
#assessments.each do |assessment|
assessment.measurements.each do |measurement|
perform operations
end
end
As I mentioned above, I wrote the following code in index action:
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
end
end
But that was wrong, because I am trying to access #assessment, where the #assessment defined in show action, not in index action. In index all assessments are defined, not a specific one. And I need just one with a specific id.
Also, putting the code in show method instead of index solved the problem.

Rails partial renders in console network response but not in view

I am trying to have my partial display search results in a rails view. When I check my console > network > preview, I see my partial rendered with the data I need but it doesn't display in my view.
Here's my app/controllers/searchs_controller.rb
def nearby_guides
#address = params[:address]
initial_array = #address.split(',')
city = initial_array[0]
state = initial_array[1].split(' ')
final_state = state[0]
country = initial_array[2]
#result = User.where("city = ?", city)
respond_to do |format|
format.html {render :partial => '/searchs/result', object: #result}
end
end
Here's my views/searchs/_result.html.erb
<h1>HELLO WORLD</h1>
<% if #result %>
<% #result.each do |r| %>
<p><%= r.firstname %></p>
<% end %>
<% end %>
Then in my views/searchs/new.html.erb
<%= render 'result' %>
This is the response I see in my console > network > preview
HELLO WORLD
Kevin
Which is exactly the response I expected but again, it doesn't display in the view. I've looked over stack overflow with no luck. Thanks so much for any and all help!
I think that this is your issue: format.html {render :partial =>
When you are rendering the result of an action as html - it needs to be a whole view, not just a partial.
Rendering partials is generally reserved for AJAX queries - where you need only part of the page and your javascript will insert it into the page in the right place. so either you need javascript, or you need to do something like: render :new

Display new.html.erb as a partial in index.html.erb

Is there a way to display the new.html.erb form_for div in index.html.erb?
I'd like to be able to add a new entry without leaving the homepage. Maybe a partial?
You can't render part of the template, only whole templete.
If you have a part that same for several templates, than put it to the partial and render partial as part of the template.
This is very simple example:
_partial.rb:
<%= form_for ... %>
...
<% end %>
new.html.erb:
render 'partial'
index.html.erb:
render 'partial'
More about partials and rendering you can read in rails guides.
I got it to work by creating a #article = Article.create in the index module of the controller. Works like a charm. No partials needed.
This method works for me.
In the links_controller.rb I added the #link to the index controller
def index
#links = Link.all
#link = Link.new
end
In the index.html.erb I added only the partial
<%= render 'form' %>
Ended up with the screen of this:
Yes partial would be better in that case. You can have a partial for that "_form.html.erb".
In that partial just put the form_for content. Let you have a Blog model and in the index you are showing the blog lists.
def index
#blog = Blog.new
#your rest code goes here
end
index.html.erb
<YOUR HTML CONTENT>
<%= render "/blogs/form" %>
_form.html.erb
<%= form_for(#blog) do |f| %>
Your code for the form
<%= end %>
If you want to keep the new action will show only the form, then you need to change the action and new.html.erb
def new
#blog = Blog.new
end
In new.html.erb
<%= render '/blogs/form' %>

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 %>

Resources