Help getting names in view for attachments in Rails - ruby-on-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 %>?

Related

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 Ajax create a new instance of a model and add a checkbox for it to a form

I have a view that renders two form partials:
matches/new.html.erb:
<%= render 'players/new' %>
<%= render 'matches/form' %>
matches/form is a form for a new Match. On the form you can add existing Players to Teams. The Players collection is rendered as a collection of checkboxes. When the form is submitted, the Teams get created with those selected Players inside them:
matches/_form.html.erb:
<%= form_for #match do |f| %>
<%= f.fields_for :team_1 do |team_1_form| %>
<%= team_1_form.label "Team 1" %><br>
<%= team_1_form.collection_check_boxes :player_ids, Player.all, :id, :name, include_hidden: false %>
<% end %>
<br>
<%= f.fields_for :team_2 do |team_2_form| %>
<%= team_2_form.label "Team 2" %><br>
<%= team_2_form.collection_check_boxes :player_ids, Player.all, :id, :name, include_hidden: false %>
<% end %>
<br>
<%= f.submit "Start Match" %>
<% end %>
In players/new you can create new Players:
players/_new.html.erb:
<%= form_for #player, remote: true do |f| %>
<%= f.text_field :name %>
<%= f.submit 'Create Player' %>
<% end %>
So the idea is, I want to be able to create a Player (which the form does do successfully, by the way) via AJAX and for that Player's checkbox to be added to the Players' checkbox collection in the view without a page refresh.
I've tried a few different things (you'll see a few commented-out things in the create.js.erb file). I've been stuck on this for days and I've googled the hell out of it. Help please!
Github repo: https://github.com/Yorkshireman/foosball
Controllers:
class PlayersController < ApplicationController
def create
#player = Player.create(name: params[:player][:name], league: current_league)
#match = Match.new
current_league.players << #player
respond_to do |format|
format.js {}
end
end
end
class MatchesController < ApplicationController
def new
#player = Player.new
#players = Player.all
#match = Match.new
end
def create
#match = Match.new(league: current_league)
if team_1_player_ids && team_2_player_ids
teams = BuildTeams.call team_1_player_ids, team_2_player_ids, current_league
InsertTeamsIntoMatch.call teams, #match
#match.save
render nothing: true
else
flash[:alert] = "Please select players for both teams"
render :new
end
end
private
def team_1_player_ids
params[:match] && params[:match][:team_1] && params[:match][:team_1][:player_ids]
end
def team_2_player_ids
params[:match] && params[:match][:team_2] && params[:match][:team_2][:player_ids]
end
end
views/players/create.js.erb:
// $("<%= escape_javascript(render partial: 'matches') %>");
// $('#new_match_div').html("<%= escape_javascript(render 'matches/new') %>");
$('#new_match').html("<%= escape_javascript(render 'matches/form') %>");
// $('#new_match').replaceWith("<p>Replaced</p>");
I think there are some inconsistencies between the link to your create_players branch and the code that you posted in this question.
I checkout out your code at https://github.com/Yorkshireman/foosball/commit/2413eb576f96333acbb02f1bb05689ae1dc47d3e (temp_branch), then made the following changes:
I replaced both #cat and #dog with #player.
I changed the contents of app/views/player/create.js.erb to read exactly as this:
$("<%= escape_javascript(render #player) %>").appendTo("#new_match");
$('#new_match').html("<p>Replaced</p>");
$('#new_match').html("<%= escape_javascript(render partial: 'matches/form') %>");
The second line has no effect on the end result, so it can be removed.
In the PlayersController#create, I added:
#match = Match.new(league: current_league)
Adding a new player successfully updates the checkboxes. If those changes do not work for you, then their might a be browser-specific JS problem that you're encountering.
Ok, so this is before any refactoring, but it works.
Thanks to sealocal, the create.js now reads:
$("<%= escape_javascript(render #player) %>").appendTo("#new_match");
$('#new_match').html("<%= escape_javascript(render partial: 'matches/form') %>");
But unfortunately, I don't fully understand what is going on here; I thought appendTo would actually render the player checkbox in the browser, but it seems the entire partial has be re-rendered on the next line? Why is this? What does appendTo do exactly?
Here's the weird thing - with the PlayersController like this:
class PlayersController < ApplicationController
def create
#player = Player.create(name: params[:player][:name], league: current_league)
#match = Match.new(league: current_league)
current_league.players << #player
respond_to do |format|
format.js {}
end
end
end
I was getting the error:
Rendered players/create.js.erb (33.7ms)
Completed 500 Internal Server Error in 314ms (ActiveRecord: 19.8ms)
ActionView::Template::Error (Missing partial players/_matches, application/_matches with {:locale=>[:en], :formats=>[:js, :html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/home/andrew/projects/foosball/app/views"
So I googled that error code and saw this (not the answer, but where the poster says, on line 3: "it is requesting a view with the same name as the model."). So I figured this must be some Rails magic, inferring the view from the #create method. SO... (drum roll)...
I tried shifting the #match line to above the #player line and BOOM! It worked!:
class PlayersController < ApplicationController
def create
#match = Match.new(league: current_league)
#player = Player.create(name: params[:player][:name], league: current_league)
current_league.players << #player
respond_to do |format|
format.js {}
end
end
end
If I'm honest, though, I'm not entirely sure why this works. For now, I have put it down to Rails, but if someone could shed some more light on it, that would be great.

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.

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

Rails flash[:notice] always nil

I cannot figure out why my rails views are not recognizing flash[:notice] or flash[:error]. I keep getting the following error regarding the partial view being rendered. The specific error is:
ActionView::Template::Error (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]):
In my controller I have
def index
#organisms = Organism.all
flash[:error] = "test"
flash[:notice] = "test"
respond_to do |format|
format.html
format.json { render :json => #organisms }
end
end
In my index.html.erb file I render out a partial through:
<%= render "shared/flash" %>
The partial has the following code.
<div id="flashes">
<% if flash[:notice] %>
<p id="flash_notice" class="messages notice"><%= flash[:notice] %></p>
<%= javascript_tag "$('#flash_notice').effect('highlight',{},1000);" %>
<% end %>
<% if flash[:error] || flash[:errors] %>
<p id="flash_errors" class="messages errors"><%= flash[:error] || flash[:errors] %></p>
<%= javascript_tag "$('#flash_errors').effect('highlight',{},1000);" %>
<% end %>
<% flash[:error] = flash[:errors] = flash[:notice] = nil %>
</div>
However, if instead of rendering the partial I throw in <%= notice %> it renders out the notice.
If I take the partial code and stick it in the top of the index.html.erb file it renders correctly. Thus, I assume that I am rendering the partial view wrongly?
Any help is much appreciated. Thanks!
Don't name your partial flash. Ruby on Rails creates a local variable with the same name as the partial. In your case, a flash local variable is being created.
Rename your partial to something other than flash and it should work.
Also, you shouldn't need to set flash to nil at the bottom of your partial. Let Rails take care of that for you.
You have to pass the flash to the partial:
<%= render 'shared/flash', flash: flash %>
Or a bit longer:
<%= render partial: 'shared/flash', locals: { flash: flash } %>

Resources