Routing error for "show" action - ruby-on-rails

Good day, there are a lot of questions on this problem here, but they don't help me.
For signed_in user I have a homepage with bookmarks and folders, which contains bookmarks belonged to this folder.
home method is in static_pages controller, which looks like this:
def home
if signed_in?
#folder = current_user.folders.build
#folders = current_user.folders.all
#bookmark = current_user.bookmarks.build
#bookmarks = current_user.bookmarks.all
end
end
This is part of home.html.erb
<div class="span3">
<table class="table table-hover table-condensed">
<%= render #bookmarks %>
</table>
</div>
<div class="span3">
<table class="table table-hover table-condensed">
<%= render #folders %>
</table>
</div>
So I have 2 tables with all bookmarks and all folders, belonged to current_user
This is _folder.html.erb from folders folder in views
<tr data-toggle="tooltip" data-placement="right" data-html="true">
<td data-href="<%= folder %>" class="bookmark"><i class="icon-folder-close"></i>
<%= link_to folder.name, folder_path %>
</td>
<td>
<%= link_to '<i class="icon-edit"></i>'.html_safe, '#' %>
</td>
<td>
<%= link_to '<i class="icon-trash"></i>'.html_safe, folder_path, method: :delete,
data: {confirm: 'Are you sure?'},
title: 'Delete folder ' + folder.name.to_s %>
</td>
</tr>
folders_controller.rb, with show method:
def show
#folder = Folder.find(params[:id])
#bookmarks = #folder.bookmarks.all
end
also resources :folders exists routes.rb
All I need is to go to localhost:3000/folder/1, when clicking on folder_name on homepage.
This is what I get:
Routing Error
No route matches {:action=>"show", :controller=>"folders"}
In rake routes everything is ok.
When put localhost:3000/folder/1 in browser, it works correctly.
Thank you!

Try Replacing:
<%= link_to folder.name, folder_path %>
with
<%= link_to folder.name, folder_path(folder) %>
as you need to provide the id to the show action.
You can get more information here

Related

bootstrap-confiirmation doesn't handle method :delete in rails app

I'm trying to use bootstrap-confirmation for an index view with datatables and a column for deleting the row item. I have it working without the confirmation, or with the default confirmation, but not with bootstrap-confirmation, it sends me to the show method, rather than the delete method of the controller. Its like it doesnt see the method: :delete
Here is the way I'm calling it in the index view. The popup confirmation displays, but when I click ok, it sends me to the show page.
<td><%= link_to '<i class="fa fa-trash-o fa-lg"></i>'.html_safe, role_path(id: role.id), method: :delete, :'data-toggle' => 'confirmation', :'data-copy-Attributes' => 'href data-method'%></td>
This following works (without confirmation), so I know my routes, controller action, etc work.
<td><%= link_to '<i class="fa fa-trash-o fa-lg"></i>'.html_safe, role_path(id: role.id), method: :delete, %></td>
Any ideas?
Heres my view:
<h1> Roles</h1>
</br>
<table width="100%" class="table table-striped table-bordered table-hover" id="roles-table">
<thead>
<tr>
<th>Roles</th>
<th>User Count</th>
<th>Delete Role</th>
</tr>
</thead>
<tbody>
<% #roles.each do |role| %>
<tr>
<td><%= role.name %>
<td><%= role.users.count %></td>
<% if (role.users.count == 0) %>
<!--td><%= link_to '<i class="fa fa-trash-o fa-lg"></i>'.html_safe, role_path(id: role.id), method: :delete, :data => {:confirm => 'Are you sure?'}%></td-->
<td><%= link_to '<i class="fa fa-trash-o fa-lg"></i>'.html_safe, role_path(id: role.id), method: :delete, :'data-toggle' => 'confirmation', :'data-copy-Attributes' => 'href data-method'%></td>
<% else %><
<td></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to "Add Role", new_role_path, class: "btn btn-success"%>
I couldn't make the library work because it doesn't provide a way to edit the popup html it generates, so, it also took for me the link to the show method and no way to delete it.
So what I did was to create a route to delete the resource that expects to receive the id from the resource and a value in the params for delete:
get 'role/:id/:delete', to: 'role#show', as: 'show_role'
Then in your controller you can check if you're receving a delete param, in order to separate between show and destroy, if you receive it, then you destroy it and redirects to the roles_url:
def show
#role = Role.find(params[:id])
if params[:delete]
#role.destroy
redirect_to roles_url
end
end
Then in your view you can use a link_to helper, passing the route created previously passing the resource and a value for the delete param, adding the data attributes Bootstrap Confirmation needs to make it work:
<%= link_to 'Destroy', show_role_path(role, delete: true), data: { toggle: 'confirmation', title: 'Delete it?' } %>

trouble coding links which insert search values into ransack form

I've coded in a page in which data from a database is pulled and subsequently when I click on what is displayed it enters a corresponding value into the search function on the application and displays the results, the code can be seen below:
course view:
<!-- Index of all Courses -->
<% provide(:title, "Course") %>
<!--containers for design/layout -->
<div class = "signinstyle">
<div class = "row">
<!--Page information -->
<%= form_tag(degree_new_path, :method => "get", id: "search-data") do %>
<table border="1" class="table">
<thead>
<tr>
<th>Courses</th>
</tr>
</thead>
<tbody>
<% #ads.each do |degree| %>
<tr>
<td> <%= link_to degree.cname, keyword_search_path(search: degree.cname) %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Select" %>
<% end %>
<!--closing the design/layout containers -->
</div>
</div>
degree controller (the above view is within this):
class Degree < ActiveRecord::Base
def Degree.search(search)
where("cname LIKE ? OR ucas LIKE ?", "%#{search}%", "%#{search}%")
end
end
search controller (as I use my keyword search in the view):
def keyword_search
#search = Degree.all.select(:uname, :cname, :ucas, :duration, :qualification, :entry).distinct.order(id: :ASC)
if params[:search]
#search_degree = Degree.search(params[:search]).order('cname ASC')
end
end
def course
#select = Degree.all.select(:uname, :cname, :ucas, :duration, :qualification, :entry).distinct.order(id: :ASC)
if params[:search]
#select_degree = Degree.search(params[:search])
end
end
I'm trying to replicate the above code so I can click on similar links which will enter data into the ransack search function I have but have been unable to do so, if anybody could help me out it would be appreciated. Below is the code I'm currently trying to get to work:
Searches controller:
def adsearch
#adsearch = Degree.ransack(params[:q])
#data = #adsearch.result
#adsearch.build_condition if #adsearch.conditions.empty?
#adsearch.build_sort if #adsearch.sorts.empty?
end
the view file:
<!-- Index of all Courses -->
<% provide(:title, "Course") %>
<!--containers for design/layout -->
<div class = "signinstyle">
<div class = "row">
<!--Page information -->
<%= form_tag(degree_new_path, :method => "get", id: "search-data") do %>
<table border="1" class="table">
<thead>
<tr>
<th>Courses</th>
</tr>
</thead>
<tbody>
<% #ads.each do |degree| %>
<tr>
<td> <%= link_to degree.subject_group, adsearch_path(name: ucas & value: degree.ucas_letter) %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Select" %>
<% end %>
<!--closing the design/layout containers -->
</div>
</div>
With the last two exerts of code it displays what I'm asking it to display on the initial view but doesn't enter the value I wish it to enter into the ransack search and as such doesn't create a search when clicked upon like the first example does.

Rails: No route matches... missing required keys: [:element_id]

So, basically, I have Features nested within Elements which is nested within Apps. The Apps show page contains a Table of Elements, and each Element has a table of Features. I know that this will look a bit messy, but I'm more worried about functionality right now, and I'll clean up the HTML later.
Full error:
Showing ~/app/views/apps/show.html.erb where line #41 raised:
No route matches {:action=>"new", :controller=>"apps/elements/features",
:element_id=>nil} missing required keys: [:element_id]
My FeaturesController (only a few methods shown for the sake of space)
class Elements::FeaturesController < ApplicationController
before_action :set_feature, only: [:show, :edit, :update, :destroy]
# GET /features
# GET /features.json
def index
#features = Feature.all
respond_with(#features)
end
# GET /features/1
# GET /features/1.json
def show
respond_with(#element.features)
end
# GET /features/new
def new
#element = Element.find(params[:element_id])
#feature.element = #element
#feature = Feature.new
end
# GET /features/1/edit
def edit
end
# POST /features
# POST /features.json
def create
#element = Element.find(params[:element_id])
#feature = Feature.new(feature_params)
#feature.element = #element
#feature.save
if #feature.save
flash[:notice] = "#{#feature.name} purchase was added to the #{#feature.element.name}."
redirect_to(#feature)
else
flash[:error] = "There was a problem adding the purchase."
render :show
end
end
My show.html.erb for Apps:
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #app.name %>
</p>
<p>
<strong>Infivewords:</strong>
<%= #app.infivewords %>
</p>
<p>
<strong>Description:</strong>
<%= #app.description %>
</p>
<div class="media">
<div class="media-body">
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Delete</th>
<tr>
</thead>
<tbody>
<% #app.elements.each do |element| %>
<tr>
<td><h4><%= element.name %></h4><br><h4><%= element.description %></h4></td>
<td>
<% element.features.each do |feature| %>
<td><h4><%= feature.name %></h4><h4><%= feature.description %></h4>
</td>
<% end %>
<td><h4><%= link_to "Delete", [#app, element], method: :delete, confirm: "Are you sure?" %></h4></td>
<td><%= link_to 'Add a Feature', new_element_feature_path(#element), class: 'pull-right' %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<br>
<br>
<%= link_to 'Add an Element', new_app_element_path(#app) %>
<br>
<%= link_to 'Edit', edit_app_path(#app) %> |
<%= link_to 'Back', apps_path %>
Routes:
Rails.application.routes.draw do
resources :apps do
resources :elements, controller: 'apps/elements'
end
resources :elements do
resources :features, except: [:index], controller: 'apps/elements/features'
end
root to: 'apps#index'
Please excuse the mess. I'm new to rails and I've been tearing my code apart trying to figure this out. Please let me know if I should post any more code. Thank you in advance!
try changing the path inside
<td><%= link_to 'Add a Feature', new_element_feature_path(#element), class: 'pull-right' %></td>
to
new_element_feature_path(element)
since you are still looping #app.elements, right?
Solution:
In view, changed params to #element.feature:
<%= link_to 'Add a Feature', new_app_element_feature_path(#element.feature), class: 'pull-right' %>

What is the proper way to organize two different views of the same model?

ROR newbie. I have read a lot, but I think I'm slow to absorb. I'm trying to create a web app with two different views of the same content:
A page full of artworks for visitors to browse by image (at the root of the site).
A page with a table listing out those same artworks and showing all the relevant attributes I've defined for them (medium, etc.) so I can review data associated with each artwork. This is supposed to be my super-lightweight admin page.
My questions are:
Since I generated this site from a scaffold, I'm currently using views/artworks/index.html.erb as the admin table view (supposed to be private), and I created a 'home' page and added some code to the 'home' view (and pages_controller) to make the artworks show up there (for the public). Am I doing this right? Is this a good method of organization?
I've installed devise and successfully hidden links for editing artworks on the page behind a sign in, but I don't know the proper way to cordon off portions of the app (e.g. the admin table page, edit pages, etc.) from the rest of the world. Should I be putting these pages in a different folder? How do I make these pages private?
Here are some snippets:
home.html.erb
<div id="artworks" class="transitions-enabled">
<% #artworks.each do |artwork| %>
<div class="box">
<%= link_to image_tag(artwork.image.url(:medium)), artwork %>
</div>
<% end %>
</div>
artworks/index.html.erb:
<div class="row">
<div class="col-xs-6 col-sm-8 col-md-4">
<h1>Listing artworks</h1>
</div>
<div class="col-xs-4 col-sm-2 col-md-2 col-md-offset-6">
<%= link_to 'New Artwork', new_artwork_path, class:"btn btn-default" %>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Image</th>
<th>Title</th>
<th>Genre</th>
<th>Category</th>
<th>Medium</th>
<th>Date</th>
<th>Dimensions</th>
<th>Availability</th>
<th>Rating</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<% #artworks.each do |artwork| %>
<tr>
<td><%= link_to image_tag(artwork.image.url(:thumb)), artwork %></td>
<td><%= artwork.title %></td>
<td><%= artwork.genre %></td>
<td><%= artwork.category %></td>
<td><%= artwork.medium %></td>
<td><%= artwork.date %></td>
<td><%= artwork.height %> x <%= artwork.width %></td>
<td><%= artwork.availability %> </td>
<td><%= artwork.rating %> </td>
<td><%= link_to 'Edit', edit_artwork_path(artwork) %></td>
<td></td>
</tr>
<% end %>
</tbody>
</table>
</div>
both pages_controller.rb and artworks_controller.rb have code like this:
def index
if params[:tag]
#artworks = Artwork.tagged_with(params[:tag])
else
#artworks = Artwork.all
end
end
pages_controller.rb:
def home
#artworks = Artwork.all
end
and the routes.rb:
get 'tagged' => 'artworks#index', :as => 'tagged'
devise_for :users
# get "artworks" => "artworks#index"
# post "artworks" => "artworks#index"
root "pages#home"
get "about" => "pages#about"
#get "users" => "users#index"
resources :artworks
Thanks in advance for your patience and help!
This can be the right way. But you have installed devise and hidden the links. But someone can directly hit the url. You need to add some authorization code which will take care that only admin user can edit the artworks. This can be done in many ways. If you have a simple application you can just add a before filter in which you can check if the user is admin then only he can access the page and call that on edit and update action. Either you can also use any authorization gem like Authority or so if it needs many roles. Hope this helps.
For making the code DRY:
before_filter :set_artworks, :only => [:home, :index]
private
def set_artworks
#artworks = Artworks.all
end
artworks/index.html.erb
<div class= 'row'>
<!-- your other source code goes here -->
</div>
You want this page to be private until the user is logged in. Then you can try this :
<% if current_user.present? %>
<div class= 'row'>
<!-- your other source code goes here -->
</div>
<% end %>
This div will be visible only if the user is logged in. for not yet signed in users this page will be private.
In order to make the edit option private :
<% if current_user.present? %>
<div id="artworks" class="transitions-enabled">
<% #artworks.each do |artwork| %>
<div class="box">
<%= link_to image_tag(artwork.image.url(:medium)), artwork %>
</div>
<% end %>
</div>
<% end %>
In any case if you want to public/private few sections then just wrap it inside the conditional if statements for views.
Still if anyone wishes then he can hit the url and enter into your action directly, in that case you can put condition in the controller.
before_action :authenticate_user!, only: [:action_1, :action_2]
Further if you need to keep things private on basis of user role, you can
always chose for cancan gem.
The simplest way of maintaining privileges is using cancancan gem.
Install it via bundler and generate model via rails generate cancan:ability. Then you have to distinguish admin users from others (e.g you can add integer "role" to User model) and write something like this in models/ability.rb#initialize
if user.admin?
can :manage, :all
else
can :read, Artwork
end
and modify controllers like this:
def index
authorize! :edit, Artwork
if params[:tag]
#artworks = Artwork.tagged_with(params[:tag])
else
#artworks = Artwork.all
end
end
This will throw an exception if not admin user will want to go to index. You can use redirect_to to inform user about that error. Add this to ApplicationController:
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end

How do I add a delete function in my cart in rails?

the cart controller - im having trouble declaring the delete function
class CartController < ApplicationController
def add
id = params[:id]
cart = session[:cart] ||= {}
cart[id] = (cart[id] || 0) + 1
redirect_to :action => :index
end
def index
#cart = session[:cart] || {}
end
end
the main item page - the link to delete the item is already defined, I'm confused in the controller part
<h1 id="prodhead">Products</h1>
<table class="catalog">
<% for item in #items %>
<tr>
<td>
<div class="image">
<%= link_to (image_tag item.image_url), item %>
</div>
</td>
<td>
<div class="title">
<%= link_to item.title, item %>
</div>
<div class="description">
<%=h item.description %>
</div>
<div class="links">
<% if session[:login] == 1 %>
<%= link_to 'Edit Item', edit_item_path(item) %> |
***<%= link_to 'Delete Item', item, :confirm => 'Are you sure?', :method => :delete %>***
<% else %>
<%= link_to "Add to Cart", :controller => :cart, :action => :add, :id => item %><br />
<% end %>
</div>
<div class="price">
<%= number_to_currency(item.price, :unit => "&dollar;") %>
</div>
</td>
</tr>
<% end %>
</table>
<% if session[:login] == 1 %>
<p><%= link_to 'New item', new_item_path %></p>
<% end %>
The Routes.rb - the route for deleting is also defined already
OnlineShop::Application.routes.draw do
get "cart/index"
get "cart/add"
get "cart/checkout"
get "cart/del"
get "site/about"
get "site/contact"
get "user/admin_login"
get "user/logout"
resources :items
Well first of all I've notice you reposted your issue however this time somewhat more descriptive, please for future issues, think before you create a ticket and take the time to edit previous tickets which need refining to keep the community clean.
OT:
I see you've created item and cart resources with basic CRUD functionality however the way you did it is not quite "The rails way" I suggest you start a project bij using the scaffold command to learn how this CRUD and routes should be implemented.
If you are willing to learn more about the topic I advice reading: http://guides.rubyonrails.org/getting_started.html
Also I've noticed you use the "h" syntax to escape your output this is only done before Rails 2.3.8 may I suggest using a newer rails version when starting out?

Resources