How to add class in rails 2.3.5 to link_to - ruby-on-rails

I have got following link_to tag But I don't know how to add html class attribute to it and explain me code edit_course_path(course) .. does. I am new to rails
<% #courses.each do |course| %>
<li class="list<%=cycle('odd', 'even')%>">
<div class="category-edit"><%= link_to "#{t('edit_text')}", edit_course_path(course) if permitted_to? :edit, :courses %></div>
<div class="category-delete"> <%= link_to(t('delete_text'), course_path(course), :method => 'delete', :confirm => "#{t('delete_confirm_msg')}") if permitted_to? :destroy, :courses %></div>
</li>
<% end %>

Generally like so:
<% for employee in #employees %>
<%= link_to 'Edit', edit_employee_path(employee) if permitted_to? :update, employee , :class => 'some-class'%>
<% end %>

Related

How to route actions based on object class with namespaced controllers in Rails 5.2?

I am refactoring my application so that users are now managed in a dedicated Administration namespace. I did the following:
routes.rb
namespace :administration do
get 'users', to: "/administration/users#index"
resources :users
resources :groups
end
The Users and Groups controller are now in the app/controllers/administration folder. They are defined as Administration::UsersController and Administration::GroupsController. The models are not namespaced.
The related links are now based on administration_users_path and administration_groups_path.
I use some partials for hamonised layout. One of them diplays Edit and Delete buttons, where this_object represents the instance passed to the locals:
_object_actions.erb
<% if this_object.is_active %>
<%= link_to [ :edit, this_object], method: :get, class: "mat-flat-button mat-button-base mat-primary" do%>
<span class="fa fa-edit"></span>
<%= t("Edit") %>
<% end %>
<%= link_to this_object, data: { confirm: t("Sure") }, method: :delete, class: "mat-flat-button mat-button-base mat-warn" do%>
<span class="fa fa-trash"></span>
<%= t("Destroy") %>
<% end %>
<% else %>
<%= link_to [ :activate, this_object], method: :post, class: "mat-stroked-button mat-button-base" do%>
<span class="fa fa-trash-restore"></span>
<%= t("Recall") %>
<% end %>
<% end %>
But coming to to Users and Groups, the path to actions is not properly built. I would need to build the URL such as /administration/users/1/edit, but it actually is /users/1/edit.
How can I make sure to build the correct URL for this purpose?
Thanks to this post Rails using link to with namespaced routes, I undestood that it is possible to add more parameters to the link_to method to build the actual link.
To call namespaced controller methods, I added the following to the links:
<%# Check if the parent is a module defined as Namespace. If not (Object) then display default link %>
<% namespace = controller.class.parent.name == 'Object' ?
nil :
controller.class.parent.name.downcase %>
<% if this_object.is_active %>
<%= link_to [ :edit, namespace, this_object],
method: :get,
class: "mat-flat-button mat-button-base mat-primary" do %>
<span class="fa fa-edit"></span>
<%= t("Edit") %>
<% end %>
<%= link_to [namespace, this_object],
data: { confirm: t("Sure") },
method: :delete,
class: "mat-flat-button mat-button-base mat-warn" do %>
<span class="fa fa-trash"></span>
<%= t("Destroy") %>
<% end %>
<% else %>
<%= link_to [ :activate, namespace, this_object],
method: :post,
class: "mat-stroked-button mat-button-base" do %>
<span class="fa fa-trash-restore"></span>
<%= t("Recall") %>
<% end %>
<% end %>
You can specify the desired route for each link_to
<%= link_to "Edit", edit_administration_user_path(this_object) %>

Undefined method 'each' for nil:NilClass, for #topics

I am trying to display a content on a page. I have:
index.html.erb
<if !user_signed_in? %>
<%= link_to 'Download Topics', resumes_url, :class => 'btn btn-danger' %>
<%= form_tag topics_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search" %>
<% end %>
<% #topics.each do |topic| %>
<div class="topic">
<h3><%= topic.title %></h3>
<p><%= topic.id %></p>
<p class="text-justify" ><%= topic.body %></p>
<p><%= topic.date %></p>
<%= image_tag topic.image.url, class: "topic-show" if topic.image? %>
</div>
<% if current_user && current_user.admin? %>
<%= link_to "Edit", edit_topic_path(topic), :class => 'btn btn-default' %>
<%= link_to "Destroy", topic, :class => 'btn btn-default', method: :delete, data: {confirm: 'Are you sure?'} %>
<% end %>
<%= link_to "Show", topic_path(topic), :class => 'btn btn-default' %>
<% end %>
<div>
<%= will_paginate #topic, renderer: BootstrapPagination::Rails %>
</end>
topics_controller.rb, index action
class TopicsController < ApplicationController
before_action :authenticate_user!, except: [:show, :index, :update, :destroy]
def index
#topics = Topic.search(params[:search]).paginate(:page => params[:page], :per_page => 5
#topics = Topic.all
end
end
And I received an error
undefined method `'each'` for `nil:NilClass`
The error is thrown at <% #topics.each do |topic| %>.
I am unsure what to do. I have tried to add:
#topics = Topic.all
to topics#index, but that does not seem to resolve the issue.
This error just means that #topics is empty.
To troubleshoot this, you need to refresh the page while watching your console.
Examine the queries being ran when these lines run:
#topics = Topic.search(params[:search]).paginate(:page => params[:page], :per_page => 5
#topics = Topic.all
If you can't spot the issue in the console, copy the query into your database GUI and run the query, modify it till you get your expected results and edit the query.
I would assume that your issue might have to do with the params being passed.
You should add this before your queries to view what params you are picking up.
p 'my params'
p params[:search]
p params[:page]
PS. I suggest making your per_page a variable, it makes it easier when going through code to see all the hard coded values and change them when they are not in the middle of a code block.

Nested Routes - Ruby on Rails

I'm trying to get a nested route like "project/:project_id/task/:task_id", but I'm not having any luck. I've set up my routes file like this:
Rails.application.routes.draw do
get 'sessions/create'
devise_for :users, path: '', path_names: { sign_up: 'users/sign_up'}
get 'teams/sign_up' => 'teams#new', as: 'new_team'
get 'teams/:id/users/:user_id' => 'teams#users_index'
get 'teams/:team_id/users/:id/complete' => 'users#show_complete', as: 'user_complete'
get 'projects/:id/tasks', to: 'projects#tasks_index'
get 'projects/:id/tasks/:id', to: 'tasks#show'
get 'teams/:id/projects/new' => 'projects#new', as: 'new_project'
post 'teams/:id/projects' => 'projects#create', as: 'projects'
root 'static#index', as: 'root'
get '/auth/twitter/callback' => 'sessions#create'
#resources :tasks do
#member do
# get :toggle_status
#end
#end
resources :projects do
resources :tasks, except: [:index], controller: 'projects/tasks'
end
resources :users, only: [:show]
resources :teams, except: [:new]
end
But I keep getting a error with my link in the projects.show.html, which is setup like this:
<h2><%= #project.name %></h2>
<%= form_for #task do |f| %>
<%= f.hidden_field :project_id, value: #project.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.label :notes %>: <%= f.text_field :notes %>
<%= f.submit "Add Task" %>
<% end %>
<% if #project.tasks.any? %>
<table class="table">
<tr>
<th>Task</th>
</tr>
<% #project.tasks.each do |task| %>
<tr>
<td>
<%= link_to task.notes %>
<%= task.status %>
</td>
<td>
<% if !task.id.nil? %>
<%= link_to "Change Status", toggle_status_task_path(task) %>
<% end %>
</td>
</tr>
<% end %>
</table>
<% end %>
<%= link_to "Edit Project", edit_project_path(#project) %> | <%= link_to "Delete Project", project_path(#project), method: :delete %>
I know I'm supposed to add a path after "<%= link_to task.notes %>", and I've ran rake:routes and tried numerous options of mine, but they all generate a URI error.
I'm not sure if it's how I've written my resources in the routes or what. Can anyone with nested routes expertise (in Ruby on Rails) please help me out? I'm in one of those online coding bootcamps and even instructors have been a little confused.
Can you try to change this get 'projects/:id/tasks/:id', to: 'tasks#show' to
get 'projects/:id/tasks/:id', to: 'tasks#show, as: 'project_task'.
And in your view <%= link_to task.notes, project_task_path(#project,task) %>
Hope it helps.
You would do this
<%= link_to task.notes, [#project, task] %>
This array will be used to generate a url based on the model names and ids of the items in the array (check out polymorphic routes for more info)
projects/:project_id/tasks/:id
btw, you'll also need it for the form
form_for [#project, #task] ...

How can I add a comment list in my posts' index.html page?

How can I add a comment list in my posts' index.html page?
It is my PostsController:
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
#comments = #post.comments.all
#comment = #post.comments.build
end
and its my posts show view:
<p id="notice"><%= notice %></p>
<p>
<h3><%= #post.name %></h3>
</p>
<p>
<%= (#post.descriptopm).html_safe %>
</p>
<%= link_to 'Edit', edit_post_path(#post), :class => "btn btn-info btn-xs" %>
<%= link_to 'Back', posts_path, :class => "btn btn-info btn-xs" %>
<h3>Comments</h3>
<% #comments.each do |comment| %>
<div>
<strong><%= comment.user_name %></strong>
<br />
<p><%= (comment.body).html_safe %></p>
</div>
<% end %>
<%= render 'comments/form' %>
and its my posts index view:
<h1>Listing posts</h1>
<%= link_to 'Create a New Post', new_post_path, :class => "btn btn-success btn-sm" %>
<% #posts.each do |post| %>
<div class="post thumbnail">
<h3><%= post.name %></h3>
<div><%= (post.descriptopm).html_safe %></div>
<div class="bottom-bottoms">
<%= link_to 'Display', post, :class => "btn btn-info btn-xs" %>
<%= link_to 'Edit', edit_post_path(post), :class => "btn btn-info btn-xs" %>
<%= link_to 'Delete', post, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-info btn-xs" %>
</div>
<h3>Comments</h3>
<% #post.comments.each do |comment| %>
<div>
<strong><%= comment.user_name %></strong>
<br />
<p><%= (comment.body).html_safe %></p>
</div>
<% end %>
<%= render 'comments/form' %>
</div>
<% end %>
the post.rb :
class Post < ActiveRecord::Base
has_many :comments
end
the comment.rb :
class Comment < ActiveRecord::Base
belongs_to :post
end
the show page show the comments well but the index cannot...
it shows the error : undefined method `comments' for #
please help me >"<
I am a newly Ruby on Rails writer
Associations
If you're using ActiveRecord association to "link" your Post and Comment model, you'll be able to call .comments on each post you have in your index
Something to note (and this lies at the core of your error) is that you will have to call the .comments method on each instance of the Post. You're currently trying to call it on an #instance variable which doesn't exist:
#app/views/posts/index.html.erb
<% #posts.each do |post| %>
<% post.comments.each do |comment| %>
<%= comment.body %>
<% end %>
<% end %>
This, of course, is only possible by using the setup you have already (has_many / belongs_to):
#app/models/post.rb
Class Post < ActiveRecord::Base
has_many :comments #-> post.comments
end
#app/models/comment.rb
Class Comment < ActiveRecord::Base
belongs_to :post #-> comment.post
end
instead of using #post in comment use post on index page. You have typo error.
<%= link_to 'Create a New Post', new_post_path, :class => "btn btn-success btn-sm" %>
<% #posts.each do |post| %>
<div class="post thumbnail">
<h3><%= post.name %></h3>
<div><%= (post.descriptopm).html_safe %></div>
<div class="bottom-bottoms">
<%= link_to 'Display', post, :class => "btn btn-info btn-xs" %>
<%= link_to 'Edit', edit_post_path(post), :class => "btn btn-info btn-xs" %>
<%= link_to 'Delete', post, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-info btn-xs" %>
</div>
<h3>Comments</h3>
<% post.comments.each do |comment| %>
<div>
<strong><%= comment.user_name %></strong>
<br />
<p><%= (comment.body).html_safe %></p>
</div>
<% end %>
<%= render 'comments/form' %>
</div>
<% end %>

How does an :as association work?

My comments model is pretty simple and works polymorphically, but I am now adding the ability to hide a comment by the author of a given record across those polymorphic associations.
class Comment < ActiveRecord::Base
attr_accessible :content, :show
belongs_to :commentable, :polymorphic => true
belongs_to :user
end
So, requests, questions, posts, submissions etc... all have comments and are accessing the comments template without issue, but I want to allow the author of the content in those models to show or hide comments (as opposed to flagging, for example) when the application identifies them as the author of the content that is being commented on.
class Request < ActiveRecord::Base
has_many :comments, :as => :commentable, :dependent => :destroy
end
So, I have everything working when there is only one model, by calling the author: #request.user,
but I'm wondering how to call an author using metaprogramming, so the comment view (with help) can determine what model is currently using the comment view.
I've done some research into metaprogramming, but have not found the answer.
Here is the code that calls the author (#request.user):
<% if #comments %>
<h1 class="mtop20">Comments</h1>
<% for comment in #comments %>
<% if signed_in? %>
<% if comment.show == true %>
<div class="well comment mtop10">
<% if current_user == #request.user or current_user.has_role? :admin %>
<%= simple_form_for [#commentable, comment] do |f| %>
<div class ="">
<%= f.input :show, :as => :hidden, :input_html => { :value => false } %>
<%= f.submit "Hide Comment", :class => 'btn btn-mini pull-right' %>
</div>
<% end %>
<% end %>
<span>
<%= image_tag comment.user.image.source(:header) %>
<%= link_to comment.user.name, comment.user %></span>
Posted <%= time_ago_in_words(comment.created_at) %> ago
</span>
<p class="mleft20 mtop10"><%= comment.content %></p>
<% if signed_in? %>
<% if current_user.id == comment.user_id or current_user.has_role? :admin %>
<%= link_to 'Edit', polymorphic_path([ comment.commentable, comment], :action => :edit),
:class => 'btn btn-mini mtop5 mleft10' %>
<%= link_to 'Delete', [comment.commentable, comment],
:confirm => 'Are you sure?',
method: :delete,
:class => 'btn btn-mini mtop5' %>
<% end %>
<% end %>
</div>
<% end %>
<% if comment.show == false %>
<p>A comment by <%= comment.user.name %> has been hidden by <%= #request.user.name %></p>
<% if current_user == #request.user or current_user.has_role? :admin %>
<%= simple_form_for [#commentable, comment] do |f| %>
<div class ="">
<%= f.input :show, :as => :hidden, :input_html => { :value => true } %>
<%= f.submit "Show Comment", :class => 'btn btn-mini btn-success' %>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<%= render "comments/form" %>
use comment.commentable.user to access the author of your post.

Resources