I am working on a app where you can add task etc. I know this is kind of weird but I just like to see how others would implement this. How would you change the following code into a helper method and use it?
The original code
<h2>My Tasks</h2>
<% task = #work.tasks %>
<% if task.empty? %>
<%= link_to 'Create a new task', new_task_path %>
<% else %>
<%= render :partial => 'notes/note', :locals => {:note => #note} %>
<% end %>
My way of doing a helper method
def task_check
task = #work.tasks
if task.empty?
link_to 'Create a new task', new_task_path
else
render :partial => 'notes/note', :locals => {:note => #note}
end
end
In my view
<%= #work.task_check %>
Personally, I wouldn't extract this out at all, this is view logic and it belongs in the views. It definitely doesn't belong in a model, but it could arguably be extracted into a helper. I'd change it slightly:
<h2>My Tasks</h2>
<% if #work.tasks.blank? %>
<%= link_to 'Create a new task', new_task_path %>
<% else %>
<%= render :partial => 'notes/note', :locals => {:note => #note} %>
<% end %>
Calling blank? instead of empty? will work even if #work.tasks is nil
.
You can't define a helper in the model. It won't have access to render, link_to or any other controller or view methods. So just define your method almost exactly as is in a file in your helpers directory, maybe application_helpers.rb or work_helpers.rb:
def task_check(work, note)
task = work.tasks
if task.empty?
link_to 'Create a new task', new_task_path
else
render :partial => 'notes/note', :locals => {:note => note}
end
end
And then call it in your view like so:
<%= task_check(work, note) %>
Related
In a Rails 3 project, I have an index list of costprojects.
I have a controller action called `viewprojects'.
I would like to add a checkbox column to the index list. Then let the user select which projects should be included in the pdf.
index:
<% #costprojects.each do |costproject| %>
<tr>
<td><%= check_box_tag "costproject_ids[]", costproject.id %></td>
...
<%= link_to 'PDF Selected', costprojects_viewprojects_path(:format => "pdf",:costproject_ids => costproject_ids[] ), :class => 'btn btn-success', :target => "_blank" %>
Controller:
def viewprojects
#costprojects = params[:costproject_ids]
respond_to do |format|
format.html
format.pdf do
render :pdf => "costprojects.pdf",
:show_as_html => params[:debug].present?,
:page_size => 'letter'
end
end
end
I'm getting:
undefined local variable or method `costproject_ids'
Update1:
Tried:
def viewprojects
#costprojects = params[:costproject_ids[]]
...
<%= link_to 'PDF Selected', costprojects_viewprojects_path(:format => "pdf",:costproject_ids[] => costproject_ids[] ), :class => 'btn btn-success', :target => "_blank" %>
I get "wrong number of arguments (0 for 1..2)"
Do I need to add form_tag and submit_tag?
Thanks for the help!
As Legendary mentioned in the comments you need to wrap this in a form. A link_to isn't going to transmit the value of the selected ids unless its contained in its query parameters, which it can't know at render time.
Try something more like this:
<%= form_tag costprojects_viewprojects_path(format: "pdf") do %>
<% #costprojects.each do |costproject| %>
<tr>
<td><%= check_box_tag "costproject_ids[]", costproject.id %>
</td>
<% end %>
...
<%= submit_tag "PDF Selected", class: "btn btn-success" %>
<% end %>
You should then be able to access the array of cost_project_ids simply with params[:cost_project_ids] in the controller, which it seems you're already doing. Note that this will send an HTTP POST, rather than a GET, so ensure your routes are correctly setup for that verb.
In my rails app I have a model Song. On one of the user's profile pages user_music_path(#user) I'm rendering all of their songs.
People can also like these songs, which is set up and working, I just want to use AJAX instead of page refreshes. The problem I'm having is when using ajax, I get the error undefined local variable or method "song" when I'm clicking the link "like".
Here is some of my code:
User's Music Page views/users/music.html.erb
...
<ul class="playlist list-group">
<%= render #songs %>
</ul>
views/songs/_song.html.erb
<li class="list-group-item">
<p class="pull-right">
<%= render :partial => 'songs/like_button', :locals => {:song => song} %>
<%= render :partial => 'songs/likes', :locals => {:song => song} %>
</p>
</li>
views/songs/_like_button.html.erb
<% if current_user.voted_on?(song) %>
<%= link_to "Unlike", unlike_song_path(song), :method => :post, :remote => true %>
<% else %>
<%= link_to "Like", like_song_path(song), :method => :post, :remote => true %>
<% end %>
views/songs/_likes.html.erb
<%= song.votes.count %>
views/songs/like.js.coffee
$("p.pull-right").html('<%= render :partial => "songs/like_button", :locals => {:song => song} %><%= render :partial => "songs/likes", :locals => {:song => song} %>');
controllers/songs_controller.rb
def like
begin
#vote = current_user.vote_for(#song = Song.find(params[:id]))
#vote.save
respond_with #song.user, :location => user_music_path(#song.user)
rescue ActiveRecord::RecordInvalid
redirect_to #song
end
end
And as mentioned earlier, the :like action worked perfectly before I starting using AJAX. I've also added respond_to :html, :js to my songs_controller. And the error I get when I try to like the song is ActionView::Template::Error (undefined local variable or method "song" for #<#<Class:0x000001028de9d0>:0x00000106ecd9f0>):
Where you have
<%= song.name %>
try instead
<%= #song.name %>
And do the same with your link_to paths and your render calls.
Do rake routes and use of of them for the link, e.g. (pseudo-code) link_to 'song', song_audio_path
Right now I have a rails partial that looks like this:
<%= render :partial => "/talk/partials/comment", :collection => #comments, :locals => {:votes => #votes} %>
I am passing in a collection of comments and another local variable.
That comment partial then goes right into using the comment variable and works fine.
I have since made another partial called '/talk/partials/comment_2014'. When I try this, I am getting the error undefined local variable or method 'comment'. From what I can gather, when I have a different partial name, something with the variable also changes. I would like to keep the same comment variable for the new partial ''/talk/partials/comment_2014'. How would I go about doing this?
Something I tried which did not work was the following:
<% #comments.each do |comment| %>
<%= render :partial => "/talk/partials/comment_2014", comment: comment, :locals => {:votes => #votes} %>
<% end %>
which did not work either.
You can do it this way
<% #comments.each do |comment| %>
<%= render "/talk/partials/comment_2014", comment: comment, votes: #votes %>
<% end %>
Or
<% #comments.each do |comment| %>
<%= render partial: "/talk/partials/comment_2014", locals: { comment: comment, votes: #votes } %>
<% end %>
Notice in the second way the comment is inside the locals.
I render an instance of a model into a partial with the following code <%= render #places %>.
I created _places.html.erb. I thought I could use the following code since the render method is supposed to iterates trhough the places collection :
<li>
<%= link_to place.name, place %>
</li>
I get this error : undefined local variable or method 'place' for #<#<Class:0x007fc1c0a4e6b8>:0x007fc1c05050a8>
I have to use to make it work :
<% #places.each do |place| %>
<li>
<%= link_to place.name, place %>
</li>
<% end%>
try this:
<%= render :partial => 'places.html', :collection => #places, :as => :place %>
Or, if you have the partial file as singular name, you can do it like this(without the variable :as)
<%= render :partial => 'place.html', :collection => #places %>
I'm trying to create a helper method for my admin links. In quite a few
views I have the code
<% if current_user %>
<%= link_to "Edit", edit_model_path(model) %>
<%= link_to "New", new_model_path %>
<%= link_to "Delete", model, :confirm => "You're a Noob", :method
=> :delete %>
<% end %>
that only display these when logged in.
I would like to do something like this in their place
<%= admin_links(model) %>
and pass the current item into the application helper method
def admin_links(m)
if current_user
a = "#{link_to "edit" edit_m_path(m)}"
a << "#{link_to "new" new_m_path}"
a << "#{link_to "Delete", m, :confirm => "Your a Noob", :method
=> :delete}"
end
end
Or something of the like.
basically you need to transform the class name of the model into something pointing to the correct path.
model_name = m.class.to_s.underscore
And then use it to call the appropriate path methods
link_to "edit", send("edit_#{model_name}_path", m)
As an aside, you don't need to put the link_tos in #{} because that function simply returns a string.
Rails provides polymorphic routes to handle this problem: http://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html
= link_to "Edit", polymorphic_path(model), :method => :put
I would use a partial for this - instead of a helper. Wherever you want to display these links in your views, simply render the partial:
<%= render :partial => "admin_links", :locals => { :model => model } %>
In _admin_links.html.erb just paste the original code:
<% if current_user %>
<%= link_to "Edit", edit_model_path(model) %>
<%= link_to "New", new_model_path %>
<%= link_to "Delete", model, :confirm => "Your a Noob", :method => :delete %>
<% end %>