Routing error in Rails 3.1 - ruby-on-rails

I am certainly losing my head/sleep over this.
This is my questions_controller.rb
class QuestionsController < ApplicationController
# GET /questions
# GET /questions.json
def index
#questions = Question.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #questions }
end
end
This is my applications_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
end
This is my rake routes:
questions GET /questions(.:format) questions#index
POST /questions(.:format) questions#create
new_question GET /questions/new(.:format) questions#new
edit_question GET /questions/:id/edit(.:format) questions#edit
question GET /questions/:id(.:format) questions#show
PUT /questions/:id(.:format) questions#update
DELETE /questions/:id(.:format) questions#destroy
home_index GET /home/index(.:format) home#index
This is my routes.rb
App::Application.routes.draw do
resources :questions
end
Error on going to http://0.0.0.0:3000/questions
uninitialized constant QuestionsController
What might be the error?

This kind of errors sometimes happen when there is a syntax error in one of files. Restart your dev server and look up for errors in its output.
Especially check line
format.html # index.html.erb
I don't think it can be written this way.

Can you make sure the controller filename is in correctly plural form?
app/controllers/questions_controller.rb
Thanks.

Related

Rails route disambiguation

Rails version: 5.2.3
Ruby version:2.0.4
In the below I am using concerns with post to overcome size limitations imposed on gets. It ends up clashing with #show and I can't figure out how to disambiguate them.
routes.rb
require 'sidekiq/web'
Rails.application.routes.draw do
concern :with_datatable do
post 'datatable', on: :collection
end
resources :organizations, concerns: [:with_datatable]
mount Sidekiq::Web, at: "/ninjas"
end
my routes are as follows:
datatable_organizations POST /organizations/datatable(.:format) organizations#datatable
organizations GET /organizations(.:format) organizations#index
POST /organizations(.:format) organizations#create
new_organization GET /organizations/new(.:format) organizations#new
edit_organization GET /organizations/:id/edit(.:format) organizations#edit {:id=>/[0-9]+/}
organization GET /organizations/:id(.:format) organizations#show {:id=>/[0-9]+/}
PATCH /organizations/:id(.:format) organizations#update {:id=>/[0-9]+/}
PUT /organizations/:id(.:format) organizations#update {:id=>/[0-9]+/}
DELETE /organizations/:id(.:format) organizations#destroy {:id=>/[0-9]+/}
sidekiq_web /ninjas Sidekiq::Web
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
Navigating to the route, /organizations/datatable.json produces this error:
OrganizationsController#show is missing a template for this request format and variant.
It thinks /organizations/datatable.json is a match for /organizations/:id/show despite having a clear route for /organizations/datatable(.:format)
Here's my controller:
class OrganizationsController < ApplicationController
def index
#title = "Organizations"
#page_description = "Organization data warehouse"
#page_icon = "institution"
#organization = Organization.new
#load = {data_table: true}
respond_to do |format|
format.html
format.json { render json: OrganizationDatatable.new(params) }
end
end
def datatable
respond_to do |format|
format.json { render json: OrganizationDatatable.new(params) }
end
end
def get_raw_records
Organization.all
end
def create
end
def edit
end
def destroy
end
def show
end
def update
end
def new
end
end
full error text:
ActionController::UnknownFormat - OrganizationsController#show is missing a template for this request format and variant.
request.formats: ["text/html"]
request.variant: []
NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.
What am I missing here?

How to define routes that include a dynamic organization name in Rails

I'm building a Rails 5.2 SaaS application that allows users to belong to many "organizations". Users will only see content for their currently active organization.
I started down the path of using subdomains, but after a little more research have decided to avoid them for now.
My new approach (to make it explicit to the user what organization they are using, support sharing links, browser history etc..) is to embed the organization name in the path. For example:
https://app.example.com/foo/posts # Posts for org "foo"
https://app.example.com/foo/posts/7 # Post for org "foo"
https://app.example.com/bar/posts # Posts for org "bar"
https://app.example.com/settings # General account settings
https://app.example.com/signin # Sign in
My problem is how to do this with Rails routes? I've tried to use a dynamic scope:
scope ':org' do
resources :posts
end
Results in errors like:
No route matches {:action=>"show", :controller=>"posts", :org=>#<Organization id: 1, name: "My Organization", ...}, missing required keys: [:id]
For the code:
# layouts/application.html.erb
<%= link_to post, post, class: 'dropdown-item' %>
Any suggestions on how to configure routes to support this use case?
Use the resources macro:
Rails.application.routes.draw do
resources :posts, except: [:new, :create]
resources :organizations, path: '/', only: [] do
resources :posts, module: :organizations, only: [:new, :index, :create]
end
end
$ rails routes:
Prefix Verb URI Pattern Controller#Action
posts GET /posts(.:format) posts#index
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PATCH /posts/:id(.:format) posts#update
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
organization_posts GET /:organization_id/posts(.:format) organizations/posts#index
POST /:organization_id/posts(.:format) organizations/posts#create
new_organization_post GET /:organization_id/posts/new(.:format) organizations/posts#new
By using the module: option you can setup a separate controller for the nested context:
# app/controllers/organizations/posts_controller.rb
class Organizations::PostsController < ApplicationController
before_action :set_organization!
# Index for posts belonging to a specific organization
# GET /:organization_id/posts
def index
#posts = #organization.posts
end
# GET /:organization_id/posts/new
def new
#post = #organization.posts.new
end
# POST /:organization_id/posts
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post, notice: 'Post was successfully created.'
else
render :new
end
end
private
def set_organization!
#organization = Organization.includes(:posts)
.find_by!(name: params[:organization_id])
end
def post_params
params.require(:post).permit(:title)
end
end
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# Index for posts belonging to all organizations
# GET /posts
def index
#posts = Post.all
end
# GET /posts/1
def show
end
# GET /posts/1/edit
def edit
end
# PATCH/PUT /posts/1
def update
if #post.update(post_params)
redirect_to #post, notice: 'Post was successfully updated.'
else
render :edit
end
end
# DELETE /posts/1
def destroy
#post.destroy
redirect_to posts_url, notice: 'Post was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def post_params
params.require(:post).permit(:title)
end
end
However you should be beware when creating routes that start with a dynamic segment - routes have priority in the order that they are defined and a route that starts with a dynamic segment will be "greedy" and swallow other routes if they are not defined first.

Edit Route No Matches Routing Error GET

Hey guys I am using Rails 5. I am trying to let my users edit there info, password etc but when I go to this route.
http://0.0.0.0:3000/users/edit/1
The error I get is
No route matches [GET] "/users/edit/1"
I do have a user with an ID of 1 and I have checked in my rails console to verify.
I have an edit template, and the edit controller and the edit method in the controller but its just not working. What am I doing wrong? All help is welcome, thank you!
ROUTES
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'pages#home'
get 'pages/tierlist', to: 'pages#tierlist'
resources :articles
get 'signup', to: 'users#new'
resource :users, except:[:new]
end
USERSCONTROLLER
class UsersController <ApplicationController
def new
#user = User.new
end
def create
#user = User.create(user_params)
if #user.save
flash[:success] = "Welcome to the OP-OR-Nah Community #{#user.username}"
redirect_to articles_path
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:username, :email, :password)
end
end
edit.html.erb
<h1>Edit your info</h1>
Also when I rake routes this is what I get back
rake routes |grep edit
edit_article GET /articles/:id/edit(.:format) articles#edit
edit_users GET /users/edit(.:format) users#edit
You have a typo in your file that is breaking the route.
Should be
resources :users, except: [:new]
That route typically should look like
"/users/:id/edit"
when you run rake:routes.
Default url for edit is pluralize_model_name/id/edit so users/1/edit. Anyway, you wrote resource and not resources so I think you have not that route. resource is a different method that generate something like
GET /user/new
GET /user
GET /user/edit
PATCH/PUT /user
DELETE /user
POST /user

Unfamiliar error: ActionController::RoutingError at /show uninitialized constant UserController?

I am getting this error:
ActionController::RoutingError at /show
uninitialized constant UserController
I have checked my routes, and controller several times and they seem fine so I will post them below
class UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:image, :name)
end
end
the route:
get 'index' => 'users#index'
get 'show' => 'user#show'
the attempted link to the show page from the index view:
<h4 class="media-heading"><%= link_to user.name, show_path %></h4>
Thanks for the help, will gladly post more info if needed.
You have an error in routes:
get 'show' => 'user#show' should be get 'show', to: 'users#show'
You don't have show action in your controller
I would use RESTful routes, which is simply:
resources :users # this will generate routes for you
You can specify which actions you want, or which you want to restrict using only or except options as #D-Side says in comments

Rails Resources are giving me headache

I am a .NET developer moving to Ruby on Rails. I have been programming in ASP.NET MVC and now trying to apply the same concepts to Rails. I created index action and now when I say home/index it automatically redirects me the "show" action which does not exists. My routes.rb file has this particular line:
resources :home
home is the home_controller.
What am I doing wrong?
class HomeController < ApplicationController
def show
end
# show all the articles
def index
#articles = Array.new[Article.new,Article.new,Article.new]
respond_to do |format|
format.html
format.xml { render :xml => #articles }
end
end
def new
#article = Article.new
respond_to do |format|
format.html
format.xml { render :xml => #article }
end
end
def create
#article = Article.new(params[:post]);
if #article.save
format.html { redirect_to(#post,
:notice => 'Post was successfully created.') }
end
end
def confirm
end
end
You can run "rake routes" to check out what rails thinks about your routes and which urls will be dispatched to which controllers.
In your case, I get:
home_index GET /home(.:format) {:action=>"index", :controller=>"home"}
home_index POST /home(.:format) {:action=>"create", :controller=>"home"}
new_home GET /home/new(.:format) {:action=>"new", :controller=>"home"}
edit_home GET /home/:id/edit(.:format) {:action=>"edit", :controller=>"home"}
home GET /home/:id(.:format) {:action=>"show", :controller=>"home"}
home PUT /home/:id(.:format) {:action=>"update", :controller=>"home"}
home DELETE /home/:id(.:format) {:action=>"destroy", :controller=>"home"}
So to get to the index action, you need to go to "/home". If you go to "/home/index", it will think "index" is the ID of the resource, thus dispatching to the show action.
However, in Rails, it's custom to use plural names for controllers, and naming them after the resource they represent (this is usually a model, but it doesn't have to be). So in your case the name of the controller should be "ArticlesController" and your routes.rb should contain "resources :articles". Rails is very anal about plural and singular names.
The big advantage of using the plural name of the resource you're accessing, is that you can now use short notations, like "redirect_to #article", "form_for #article do |f|", etc.
So, resources in Rails are supposed to be telling about what you want your actually getting. This helps maintenance too, since other developers have to guess less. If you find yourself needing more than one ArticlesController, consider using namespaces, or try to figure out if one of those controllers are actually another resource (even though they store their data in the same database table).
More information about the routers can be found in the Rails Guide: http://guides.rubyonrails.org/routing.html

Resources