How to DRYing action buttons in Rails 4? - ruby-on-rails

I have a dozen different Views/Controllers for administrator. In every view I have got something like this:
<%= link_to edit_topic_path(topic) do %>
<span class="glyphicon glyphicon-pencil"></span>
<% end %> |
<%= link_to topic, method: :delete, confirm: "Are you sure?" do %>
<span class="glyphicon glyphicon-trash"></span>
<% end %>
Now my question is, How can I DRY this so I just pass some vars or object to a method and generate the above code for different views.
Thank you.

You should crate a partial
_controls.html.erb
<%= link_to path do %>
<span class="glyphicon glyphicon-pencil"></span>
<% end %> |
<%= link_to model, method: :delete, confirm: "Are you sure?" do %>
<span class="glyphicon glyphicon-trash"></span>
<% end %>
Then you can call it as follows:
<%= render :partial => "controls", :locals => {:path => edit_topic_path(topic), :model => topic} %>

Related

How do I output the contents of a variable in grid form?

I have the following code for my Ruby on Rails project, which outputs a list of users on a page:
<ul class="users">
<%= render #users %>
</ul>`
The result is a long list of users on the page.
My question is: How can I manipulate #users so that I can output its content in grid form (e.g., a row of 5 users and then next row and then next and so on) on the page? Thanks.
This is a really simple example and you can customise into a nicer table.
The basic idea is to group the array of users in subarrays of n elements, lets say 5.
<% #users.each_slice(5).each do |row| %>
<p><% row.each do |user| %>
<%= user.name %> |
<% end %>
</p>
<% end %>
<div class="row">
<% users.in_groups_of(5) do |group| %>
<% group.compact.each do |user| %>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<%= image_tag (user.file_url), class: "img-sz" %>
<h4><%= link_to user.title, user %></h4>
<%= link_to "Edit", edit_user_path(user) , remote: true, class: "btn btn-default btn-xs" %>
<%= link_to "delete", user,remote: true, method: :delete, data: { confirm: "You sure?" }, class: "btn btn-danger btn-xs" %></br></br>
</div>
<% end %>
<% end %>
<% end %>
</div>
This is example code change the name of attributes according to your structure . This will help you in solving your problem .

Trying to adapt code form one of my views to be rendered in a partial

I have a partial that takes a column from a database a iterates over it and displays all the urls on the web page. I want to add the lines that I have written in my app/views/topics/show.html.erb page that allow the user to edit, delete, or like the link.
These are the three lines I want to adapt to be added to the partial, the first two are buttons to carry out the edit and delete function and the third is a link to a partial with the like code.
<%= link_to "Edit bookmark", edit_topic_bookmark_path(bookmark.topic, bookmark), class: 'btn btn-primary btn-xs'%><br>
<%= link_to "Delete bookmark", [bookmark.topic, bookmark], method: :delete, class: 'btn btn-danger btn-xs', data: { confirm: 'Are you sure you want to delete this bookmark?' } %>
<%= render partial: 'likes/likes', locals: { bookmark: bookmark } %>
this is the partial I would like to adapt it to located in app/views/bookmarks/_bookmarksandlikes.html.erb
<div>
<h3>
<%y=1%>
<% mark.each do |x| %>
<%=y%>)<%= link_to x.url, x.url%>
<%y=y+1%>
<% end %>
</h3>
</div>
and it is being called from app/views/users/show.html.erb with these two lines.
<%= render partial: 'bookmarks/bookmarksandlikes', locals: { mark: #bookmarks} %>
<%= render partial: 'bookmarks/bookmarksandlikes', locals: { mark: #liked_bookmarks} %>
here is how I have tried to insert the code into the partial
<div>
<h3>
<%y=1%>
<% mark.each do |x| %>
<%=y%>)<%= link_to x.url, x.url%>
<%y=y+1%>
<%= link_to "Edit bookmark", edit_topic_bookmark_path(x.topic, x), class: 'btn btn-primary btn-xs'%><br>
<%= link_to "Delete bookmark", [x.topic, x], method: :delete, class: 'btn btn-danger btn-xs', data: { confirm: 'Are you sure you want to delete this bookmark?' } %>
<%= render partial: 'likes/likes', locals: { x: x } %>
<%end%>
</h3>
when I run the code as is I get an error page that says "undefined local variable or method 'bookmark' for #<#<Class:0x007fdfb1b39c80>:0x007fdfb1988d50> Did you mean? bookmark_url or #bookmarks
and says there is a problem on line 3 of the partial with the code for liking a page in app/views/likes/_likes.html.erb
<% if policy(Like.new).create? %>
<div>
<% if like = current_user.liked(bookmark) %>
<%= link_to [bookmark, like], class: 'btn btn-danger', method: :delete do %>
<i class="glyphicon glyphicon-star-empty"></i> Unlike
<% end %>
<% else %>
<%= link_to [bookmark, Like.new], class: 'btn btn-primary', method: :post do %>
<i class="glyphicon glyphicon-star"></i> Like
<% end %>
<% end %>
</div>
<% end %>
side note at this point in working through this problem, it appears that only the third line for the partial I am trying to insert is giving me problems, the edit and delete buttons are rendering nicely.
Even if you don't know the answer I am quite keen to hear any thoughts on what I am not considering in this question or just your thoughts, also if you need more information please just let me know and I will post more.
Thanks for looking at my question.
I figured out my problem, I could not use the partial because the partial app/views/likes/_likes.html.erb was taking in a different variable than was being passed by app/views/bookmarks/_bookmarksandlikes.html.erb so I just put the needed code into app/views/bookmarks/_bookmarksandlikes.html.erb and adapted it like so.
<div class=row>
<h3>
<%y=1%>
<% mark.each do |x| %>
<%=y%>)<%= link_to x.url, x.url%><br>
<%y=y+1%>
<%= link_to "Edit bookmark", edit_topic_bookmark_path(x.topic, x), class: 'btn btn-primary btn-xs'%><br>
<%= link_to "Delete bookmark", [x.topic, x], method: :delete, class: 'btn btn-danger btn-xs', data: { confirm: 'Are you sure you want to delete this bookmark?' } %><br>
<% if like = current_user.liked(x) %>
<%= link_to [x, like], class: 'btn btn-danger', method: :delete do %>
<i class="glyphicon glyphicon-star-empty"></i> Unlike
<% end %>
<% else %>
<%= link_to [x, Like.new], class: 'btn btn-primary', method: :post do %>
<i class="glyphicon glyphicon-star"></i> Like
<% end %>
<br>
<% end %>
<%end%>
</h3>
</div>

RAILS 4: problems with 'delete' button

I have a nested resource, comments like so....
resources :microposts do
member do
get :upvote, :undo_upvote
end
member do
get :follow, :unfollow
end
resources :responses do
member do
get :upvote, :undo_upvote
end
resources :comments
end
end
I have a delete button on the comments index page....
<div class = "Comment" id="comment-<%= comment.id %>">
<%= link_to comment_avatar_for(comment.user), comment.user %>
<span class="Commentator">
<%= comment.user.full_name %>
</span>
<span class="content">
<%= comment.body %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(comment.created_at) %> ago.
</span>
<span class="timestamp">
<% if current_user?(comment.user) %>
<%= link_to "delete", comment, method: :delete, data: { confirm: "You sure?" }, :class => "btn btn-default btn-xs delete" %>
<% end %>
</span>
</div>
And I am getting this error when I load the page
undefined method `comment_path' for #<# <Class:0x007f8936876e70>:0x007f8931857020>
I am uncertain why this isn't working - after all I have the correct instance of 'comment'. If someone could just point me in the right direction I would be grateful.
Rails makes assumptions.
Because you have an instance of Comment it assumes you're going to be using comment_path, but you don't have that as per your routes so you need to set the correct path:
<%= link_to "delete", micropost_response_comment_path(#micropost, #response, comment), method: :delete, data: { confirm: "You sure?" }, :class => "btn btn-default btn-xs delete" %>
I might have the path wrong, but hopefully you get the idea.

Passing HTML from serverside to datatables

I am changing my Datatables to load content from my Rails app. In one of the cells I have a big chunk of HTML, and since when using the server-side approach the cells are printed with Javascript, I would need to pass the HTML from Rails.
So, here is how it looks one of the cells with datatables WITHOUT server side fetching:
<td>
<div class='order-actions-container'>
<div class='order-action'>
<%= link_to 'Show pages', admin_order_pages_path(order.id), :class => 'btn btn-primary' %>
</div>
<% if order.status.name == 'reviewed' %>
<div class='order-action'>
<%= form_tag(admin_order_set_completed_status_path(order), :method => 'patch' ) do %>
<%= submit_tag 'Complete order', class: 'btn btn-success', data: { confirm: 'Are you sure you want to complete this order?' } %>
<% end %>
</div>
<% end %>
<% if order.status.name == 'queued' %>
<div class='order-action'>
<%= form_tag(admin_order_process_order_path(order), :method => 'post' ) do %>
<%= submit_tag 'Process order', class: 'btn btn-success', data: { confirm: 'Are you sure you want to process this order?' } %>
<% end %>
</div>
<% end %>
<% if order.status.name != 'processing' %>
<div class='order-action'>
<%= form_tag(admin_order_path(order), :method => 'delete' ) do %>
<%= submit_tag 'Delete order', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete this order?' } %>
<% end %>
</div>
<% end %>
</div>
</td>
Now, since all the data will come back from Rails, I would need to pass that HTML via a JSON. Isn't that breaking the MVC? How do you deal in these situations?
If you are wanting to use json with ajax for datatables you can use JBuilder or rabl to create a json document that can be easily reused.
Also there is not a need to write out form_tags wrapped around submit_tags to call different methods, with rails you can use link_to and specify the :method to accomplish the same thing.
<td>
<div class='order-actions-container'>
<div class='order-action'>
<%= link_to 'Show pages', admin_order_pages_path(order), :class => 'btn btn-primary' %>
</div>
<% if order.status.name == 'reviewed' %>
<div class='order-action'>
<%= link_to "Complete order", admin_order_set_completed_status_path(order), method: :patch, class: 'btn btn-success', data: { confirm: 'Are you sure you want to complete this order?' }%>
</div>
<% end %>
<% if order.status.name == 'queued' %>
<div class='order-action'>
<%= link_to "Process order", admin_order_process_order_path(order), method: :post, class: 'btn btn-success', data: { confirm: 'Are you sure you want to process this order?' }%>
</div>
<% end %>
<% if order.status.name != 'processing' %>
<div class='order-action'>
<%= link_to "Delete order", admin_order_path(order), method: :delete, class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete this order?' }%>
</div>
<% end %>
</div>
</td>

Only Admin Role Can Edit or Delete Notes Rails 4

I am having a simple issue but nonetheless unable to figure it out. My employee role can not edit or delete notes but they can view them & they can also create them.
My admin role however can view, create, edit & delete. My employee section is working but my admin is not. I am still new to rails so please bear with my ignorance.
My error is "NameError in Notes#index" and "undefined local variable or method `note' for #<#:0x007fa7b580c0a0>"
In my notes/index.html.erb file my code is as follows:
<% if #user.role == "employee" %>
<%= link_to 'New Note', new_note_path, class: "btn btn-primary btn-lg" %>
<% #notes.each do |note| %>
<div class="row notes-row"><h1><%= note.title %></h1></div>
<div class="row notes-row"><h3>Created By: </h3><%= note.user_name %></div>
<div class="row notes-row"><h6>Posted On:</h6><%=note.created_at%></div>
<div class="row notes-row"><%= note.text_box %></div>
<br>
<p><%= link_to 'View', note %></p>
<br>
<hr>
<% end %>
<% elsif #user.role == "admin" %>
<%= link_to 'Add New Job', new_job_path, class: "btn btn-primary btn-lg" %>
<%= link_to 'Edit', edit_note_path(note) %><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' } %>
<br>
<p> <% #notes.each do |note| %> | </p>
<%= link_to 'View', note%>
<%end%>
<% end%>
My index method is :
def index
#users = User.all
#user = current_user
#notes = Note.all
#notes = Note.paginate(:page => params[:page],:per_page => 5)
end
Your error arises from this point;
<%= link_to 'Edit', edit_note_path(note) %><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' } %>
The variable note is unknown at this point.
You could re-factor it this way;
<% if #user.role == "employee" %>
<%= link_to 'New Note', new_note_path, class: "btn btn-primary btn-lg" %>
<% end %>
<% #notes.each do |note| %>
<% if #user.role == "employee" %>
<div class="row notes-row"><h1><%= note.title %></h1></div>
<div class="row notes-row"><h3>Created By: </h3><%= note.user_name %></div>
<div class="row notes-row"><h6>Posted On:</h6><%=note.created_at%></div>
<div class="row notes-row"><%= note.text_box %></div>
<br>
<p><%= link_to 'View', note %></p>
<br>
<hr>
<% end %>
<% if #user.role == "admin" %>
<%= link_to 'Add New Job', new_job_path, class: "btn btn-primary btn-lg" %>
<%= link_to 'Edit', edit_note_path(note) %><%= link_to 'Destroy', note, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
<% end %>
<br>
<% if #user.role == "admin" %>
<p> <% #notes.each do |note| %> | </p>
<%= link_to 'View', note%>
<%end%>
<% end %>
The code can be cleaned up further.

Resources