routes error in rails - ruby-on-rails

I am working on a project. I am making an application where a user can add an issue (like a post) and the user can comment on it.
on running this application, I get an error
Couldn't find Issue with 'id'=show
the code for routes file is
resources :issues do
resources :comments
end
get 'users/new'
get 'users/create'
get 'users/show'
get 'users/edit'
get 'issues/show/:id', :to => 'issues#show'
resources :users
resources :sessions, :only => [:create, :new,:destroy]
get '/signup', :to => 'users#new'
get '/signin' , :to => 'sessions#new'
get '/signout', :to => 'sessions#destroy'
the code for the issues controller is
class IssuesController < ApplicationController
def new
#issue = Issue.new
end
def create
#issue = Issue.new(issues_params)
if #issue.save
flash[:success]='your issue has been raised'
redirect_to :controller => 'issues', :action => 'show', :id => #issue.id
else
render 'new'
end
end
def edit
#issue = Issue.find(params[:id])
end
def update
#issue = Issue.find(params[:id])
if #issue.update_attributes(issues_params)
redirect_to :controller => 'issues', :action => 'show', :id => #issue.id
else
render 'edit'
end
end
def index
#issues = Issue.all
end
def show
#issue = Issue.find(params[:id])
end
def destroy
#issue=Issue.find(params[:id])
#issue.destroy
redirect_to :controller => 'issues', :action => 'index'
end
protected
def issues_params
params.require(:issue).permit(:title,:content)
end
end
the code for the comments controller from where I call the show method in issues controller is
class CommentsController < ApplicationController
def create
#issue = Issue.find(params[:issue_id])
#comment = #issue.comments.create(comment_params)
if #comment.save
redirect_to :controller => 'issues', :action => 'show', :id => #issue[:id]
else
render 'new'
end
end
private
def comment_params
params.require(:comment).permit(:content)
end
end

You must be trying to request the URI /issues/show? This will map to the GET /issues/:id from the resources :issues do line of your routes. The router will set the params[:id] to the string "show" and send the request to the show action of the IssuesController which, as you've shown, will then try to do Issue.find(params[:id]) ie. Issue.find("show") and hence you get your error.

Change this
resources :issues do
resources :comments
end
to
resources :issues, except: [:show] do
resources :comments
end
It will resolve your problem!

Related

Couldn't find Product with 'id'=search

I'm just starting with RoR and i got an issue.
Earlier, I asked hear and nobody could fix it. I would like to make a simple search form, where i would search for a product name(title).
Here is the issue: "Couldn't find Product with 'id'=search"
Picture with the error
Here is my controller:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
helper_method :get_cost
# GET /products
def index
#products = Product.all
#products = Product.search(params[:find])
end
# GET /products/1
def show
end
# GET /products/new
def new
#product = Product.new
# ingredients_ids = #product.ingredients
end
# GET /products/1/edit
def edit
end
# POST /products
def create
#product = Product.new(product_params)
if #product.save
redirect_to #product, notice: 'Product was successfully created.'
else
render :new
end
end
# PATCH/PUT /products/1
def update
if #product.update(product_params)
redirect_to #product, notice: 'Product was successfully updated.'
else
render :edit
end
end
# DELETE /products/1
def destroy
#product.destroy
redirect_to products_url, notice: 'Product was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def product_params
params.require(:product).permit(:title, :description, :category, :price, :quantity, {ingredient_ids: []})
end
end
Here is my model:
class Product < ActiveRecord::Base
has_and_belongs_to_many :ingredients
has_and_belongs_to_many :orders
enum category: ["Culinária Italiana", "Culinária Oriental", "Culinária Árabe", "Culinária Brasileira"]
TITLE_MIN_LENGTH = 3
DESCRIPTION_MIN_LENGTH = 2
validates :title, presence: true, :length => {:minimum => TITLE_MIN_LENGTH}, uniqueness: true
validates :description, presence: true, :length => {:minimum => DESCRIPTION_MIN_LENGTH}
def self.search(search)
if search
where(["title LIKE ?", "%#{search}%"])
else
all
end
end
end
here is my view:
<%= form_tag(products_search_path, :method => :get) do%>
<%= text_field_tag :find, nil, placeholder:"Insira o que está procurando"%>
<%= submit_tag "Pesquisar", :name => nil %>
<% end %>
And just to finish, here is my routes:
Rails.application.routes.draw do
get 'sessions/new'
get 'users/new'
get 'orders/show'
get 'orders/new'
resources :ingredients
resources :products do
get 'search'
end
resources :orders
root "home#index"
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get 'home/about'
get 'home/contact'
get "home" => "home#index"
end
Thanks for the attention, Miguel.
You have a get 'search' in your routes.rb, but there is not def search in your controller. So it thinks you're trying to access the show page:
GET products/[id] where the [id] is search (which is clearly invalid, since all ids are numbers).
If you want to keep that search route, then you should set it as:
get 'search', on: :collection. And add def search to your controller with your search logic.
Edit:
Just adding a few tips:
In the def index method, this line #products = Product.all is unnecessary, since you overwrite it in the following line;
Instead of creating a different route for the search, it's recommended that you use the index with a query string. So you should:
remove the get 'search' from the routes.rb;
change your search form path to products_path instead of products_search_path;
search is a collection method, so the route needs to be...
resources :products do
collection do
get 'search'
end
end

No route matches {:controller=>"submissions"}

I get this error when I'm running a test that simply does get :index. Here is the test code:
class SubmissionsControllerTest < ActionController::TestCase
setup do
#submission = submissions(:one)
end
test "should get index" do
get :index
assert_response :redirect
# assert_not_nil assigns(:submissions)
end
I have a route set up for this controller though in my routes.rb file:
resources :courses do
resources :assignments do
get 'export', :controller => 'assignments', :action => 'export'
resources :memberships
resources :submissions do
resources :evaluations do
delete 'destroy', controller: 'reviews', action: 'destroy'
end
end
resources :questions do
resources :responses
resources :scales
end
resources :reviews do
get :assign_reviews, :on => :collection
post :edit_review, :on => :collection
end
end
end
Also, this is what I get for submissions routes when I run rake routes:
course_assignment_submissions GET /courses/:course_id/assignments/:assignment_id/submissions(.:format) submissions#index
POST /courses/:course_id/assignments/:assignment_id/submissions(.:format) submissions#create
new_course_assignment_submission GET /courses/:course_id/assignments/:assignment_id/submissions/new(.:format) submissions#new
edit_course_assignment_submission GET /courses/:course_id/assignments/:assignment_id/submissions/:id/edit(.:format) submissions#edit
course_assignment_submission GET /courses/:course_id/assignments/:assignment_id/submissions/:id(.:format) submissions#show
PUT /courses/:course_id/assignments/:assignment_id/submissions/:id(.:format) submissions#update
DELETE /courses/:course_id/assignments/:assignment_id/submissions/:id(.:format) submissions#destroy
And here is my code for the index action:
def index
if !current_user.instructor?(#course)
raise CanCan::AccessDenied.new("Not authorized!")
end
registrations = #course.registrations
#students = registrations.select{|r| !r.user.pseudo or #assignment.memberships.any?{|m| m.pseudo_user_id == r.user_id } }.map{|r| r.user }
respond_to do |format|
format.html # index.html.erb
format.json { render json: #students }
end
end
Does anyone know where this error could be coming from then?
Because your submissions controller is nested into assignments and assignments into courses you have to pass an :assignment_id and a :course_id into your get request.
So for example:
get :index, course_id: your_course, assignment_id: your_assignment

Connection between controller and view in rails

In users_controller.rb I've got my method:
def showallusers
#users = User.all
respond_to do |format|
format.html # showallusers.html.erb
format.json { render :json => #users }
end
end
and in app/views/users I've got showallusers.html.erb and in it:
<p>test</p>
but when I type
http://localhost:3000/users/showallusers
in browser, it shows me show.html.erb instead.
My routes.rb
resources :users
resources :projects do
resources :issues
end
#resources :issues
resources :projects
resources :sessions
root :to => "users#index"
match "/auth/:provider/callback" => "sessions#create"
match "/signout" => "sessions#destroy", :as => :signout
Do you know, what is wrong and how can I fix it? thanks
In your routes.rb:
resources :users do
collection do
get :showallusers # why not :show_all_users? Isn't it more readable?
# you may also need
# post :showallusers
end
end
Then restart your server to make sure the new url-helpers are generated (the new helper should be showallusers_users_path)

Rails - passing object's id

I'm creating a message-board site using ruby on rails.
I generated two scaffolds: Topic and Forum. Topic belongs_to Forum.
when the user is creating a new topic, I should pass the forum_id (a GET var). something like:
http://example.com:3000/topics/new/1
and then, when the user submit the form he passes back the forum_id with the POST request (through hidden html field?).
what is the right way doing it?
thanks
routes:
resources :forums
get "admin/index"
resources :posts
resources :topics
resources :users
match '/signup', :to => 'users#new'
get '/login', :to => 'sessions#new', :as => :login
match '/auth/:provider/callback', :to => 'sessions#create'
match '/auth/failure', :to => 'sessions#failure'
match '/topics/new/:id', :to => 'topics#new'
A good way to do it is to nest topics resources inside forums resources like this:
resources :forums do
resources :topics
end
Then in your TopicsController
class TopicsController < ApplicationController
def new
#forum = Forum.find params[:forum_id]
#topic = Topic.new
end
def create
#forum = Forum.find params[:forum_id] # See the redundancy? Consider using before_filters
#topic = #forum.topics.build params[:topic]
if #topic.save
redirect_to #topic
else
render action: :new
end
end
end
And finally in your views/topics/_form.html.erb:
<%= form_for [#forum, #topic] do |f| %>
# Your fields
<% end %>

No route matches {:action=>"up_vote", :controller=>"votes", :post_id=>"1"}

I've been receiving the following error in my RSpec when trying to get my upvote method to pass:
Failures:
1) VotesController#up_vote adds an up-vote to the post
Failure/Error: post( :up_vote, post_id: #post.id )
ActionController::UrlGenerationError:
No route matches {:action=>"up_vote", :controller=>"votes", :post_id=>"1"}
Now I can upvote and downvote when I'm on the server, it's just my test that won't work.
Here's my code:
votes_controller_spec.rb
require 'rails_helper'
describe VotesController do
include TestFactories
include Devise::TestHelpers
describe '#up_vote' do
it "adds an up-vote to the post" do
request.env["HTTP_REFERER"] = '/'
#user = authenticated_user
#post = associated_post
sign_in #user
expect {
post(:up_vote, post_id: #post.id)
}.to change { #post.up_votes }.by 1
end
end
end
votes_controller.rb
class VotesController < ApplicationController
before_action :load_post_and_vote
def up_vote
update_vote!(1)
redirect_to :back
end
def down_vote
update_vote!(-1)
redirect_to :back
end
def update_vote!(new_value)
if #vote
authorize #vote, :update?
#vote.update_attribute(:value, new_value)
else
#vote = current_user.votes.build(value: new_value, post: #post)
authorize #vote, :create?
#vote.save
end
end
private
def load_post_and_vote
#post = Post.find(params[:post_id])
#vote = #post.votes.where(user_id: current_user.id).first
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:update]
resources :questions
resources :advertisements
resources :topics do
resources :posts, except: [:index] do
resources :summaries, only: [:create, :new, :show]
resources :comments, only: [:create, :destroy]
post '/up-vote', to: 'votes#up_vote', as: :up_vote
post '/down-vote', to: 'votes#down_vote', as: :down_vote
end
end
get 'about' => 'welcome#about'
get 'contact' => 'welcome#contact'
root to: 'welcome#index'
end
Module providing methods within specs:
module TestFactories
def associated_post(options={})
post_options = {
title: 'Post title',
body: 'Post bodies must be pretty long.',
topic: Topic.create(name: 'Topic name'),
user: authenticated_user
}.merge(options)
Post.create(post_options)
end
def authenticated_user(options={})
user_options = {email: "email#{rand}#fake.com", password: 'password'}.merge(options)
user = User.new(user_options)
user.skip_confirmation!
user.save
user
end
end
Relevant Rake Routes
topic_post_up_vote POST /topics/:topic_id/posts/:post_id/up-vote(.:format) votes#up_vote
topic_post_down_vote POST /topics/:topic_id/posts/:post_id/down-vote(.:format) votes#down_vote
Any ideas why I'm getting this URL generation error?
I think you just need to pass the topic_id to the post method like this: post( :up_vote, post_id: #post.id, topic_id: #post.topic.id )
I ended up switching my routes.rb file to the below and got the above vote_controller_spec.rb working.
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:update]
resources :questions
resources :advertisements
resources :topics do
resources :posts, except: [:index]
end
resources :posts, only: [] do
resources :summaries, only: [:create, :new, :show]
resources :comments, only: [:create, :destroy]
post '/up-vote', to: 'votes#up_vote', as: :up_vote
post '/down-vote', to: 'votes#down_vote', as: :down_vote
end
get 'about' => 'welcome#about'
get 'contact' => 'welcome#contact'
root to: 'welcome#index'
end

Resources