How to access related models in RoR after using link_to? - ruby-on-rails

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.

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

removing specific content from a feed with ajax js.erb when a user is unfollowed

I have a follow form that is rendered in numerous areas of my app. There is a feed view, where content of followed users is shown. When a user is unfollowed I need that page to be updated to remove the content of the unfollowed user. So one solution would be to put all the feed content into a partial and render that partial after a relationship is destroyed through the destroy.js.erb ajax file that is triggered from the Relationships Controller.
UsersController
def feed
#user_feed_items = current_user.photo_feed.order('created_at desc').paginate(page: params[:page])
end
class User
def photo_feed
following_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
Photo.approved.where("user_id IN (#{following_ids})", user_id: id)
end
feed.html.erb
<%= render 'shared/feed' %>
end
_feed.html.erb
<% if #user_feed_items.any? %>
<% #user_feed_items.each do |feed| %>
<div class="feed-content">
<%= render partial: "users/usersforfeed", locals: { feed: feed } %>
</div>
<% end %>
<% end %>
Now the Relationships Controller looks like this:
def destroy
#user = Relationship.find(params[:id]).followed
current_user.unfollow(#user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
end
All that is being passed to the relationships controller through the follow form are the user.id's of the followed and follower users.
So in destroy.js.erb:
$('.feed-content').html("<%= escape_javascript(render(partial: 'users/usersforfeed', locals: { feed: ???? ))
I cannot render the partial because I have nothing to match up with the feed variable??
I put a wrapper around each object and then simply removed it with javascript if the user is unfollowed. This is easier than rendering the feed again and nothing is gained in rendering the feed anew.

Rails render partial from controller

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

Flash messages in Rails 3.2.3 and json

There is an action in a controller. It can be called only with json format via ajax.
def update
#article = Article.find_by_id params[:id]
respond_to do |format|
if #article.update_attributes(params[:article])
flash[:message] = "good"
else
flash[:error] = #article.errors.full_messages.join(", ")
end
format.json { render :json => flash}
end
end
the part of a page
<% unless flash[:error].blank? %>
<%= flash[:error] %>
<% end %>
<% unless flash[:message].blank? %>
<%= flash[:notice] %>
<% end %>
<!-- page content goes -->
Of course, a page contains a button_to with :remote=>true that calls the method update.
The bottom line is that it shows nothing after updating. JSON object definitely returns, I can see it in fireBug.
The question is, am I using flash correctly? And how do I use it to show a message on a page? Please don't forget about ajax.
Why do you have an if/else statement in your respond_to block?
def update
#article = Article.find_by_id params[:id]
if #article.update_attributes(params[:article])
flash[:notice] = "Good"
else
flash.now[:notice] = "Bad"
render "edit"
end
respond_to do |format|
format.html {redirect_to #article}
format.js
end
end
Then create update.js.erb
$("#notice").text("<%= escape_javascript(flash[:notice]) %>")
$("#notice").show()
Code above might not be 100% correct.
For flash, I'd have something like:
<div id="notice">
<% flash.each do |key, value| %>
<%= content_tag(:div, value, :class => "flash #{key}") %>
<% end %>
</div>
This posting has all the code you'll need. It saved my hide:
https://gist.github.com/linjunpop/3410235
Here's a fork of it that makes a few minor modifications:
https://gist.github.com/timothythehuman/5506787
I think
You have to bind ajax:success call back which will display flash message by replacing message or placing message to dom.

Help getting names in view for attachments in Rails

I want to display attachments in my asset view and I have this in my view:
<% if #asset.attachments.size > 0 %>
<% #asset.attachments.each_with_index do |attachment| %>
<%= image_tag attachment.to_s %>
<%end%>
<%end%>
and I have this in my controller (just the basic):
def show
#asset = Asset.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #asset }
end
end
When I want it to show the name (which is in the attachment field of the attachments table). But the code only gives me
#<attachment #<attachment
as output in the view. What am I missing?
Calling attachment here is just referencing the class it looks like. Is there a name field for attachment so you could call something like <%= image_tag attachment.name %>?

Resources