Rails routing error with long class names - ruby-on-rails

I get confused at Rails pluralising and camelcasing. Especially with my long but clear names.
I have a User model and an Account model. I also have a user_to_account_log_history model and controller for saving transfers between the two. The relationships are setup.
I ran...
$ rails generate controller UserToAccountLogHistories
...which created the following:
# app/controllers/user_to_account_log_histories_controller.rb
class UserToAccountLogHistoriesController < ApplicationController
# a simple index method
end
# app/models/user_to_account_log_history.rb
class UserToAccountLogHistory < ActiveRecord::Base
end
My routes seems to be in place (rake routes output, truncated):
user_usertoaccountloghistories GET /users/:user_id/usertoaccountloghistories(.:format) {:action=>"index", :controller=>"usertoaccountloghistories"}
But I'm getting an uninitialized constant UsertoaccountloghistoriesController. Why? I get the feeling it´s the long names camelcasing and pluralising that messes things up.

The problem is that you have a class called UserToAccountLogHistoriesController but no class called UsertoaccountloghistoriesController -- note the difference in capitalisation here.
It's not clear from your question exactly how you've defined your route, but I suspect that you've got a route referring to usertoaccountloghistories when actually you want to refer to user_to_account_log_histories.
In the rails console, observe the following:
> "hello_world".camelize
# => "HelloWorld"
> "helloworld".camelize
# => "Helloworld"

Related

Rails model name lookup: strange uninitialized constant error

I have a controller that should output suggestions for a form. The controller is under the Admin::Shop namespace and is located at app/controllers/admin/shop/suggest_controller.rb
class Admin::Shop::SuggestController < Admin::AdminsAreaController
def index
render:json => Shop::Product.all.group(:name).pluck(:name) and return
end
end
Shop::Product is a model defined under app/models/shop/product.rb as follows:
class Shop::Product < PostgresRecord
# ...
end
I can run queries on this model from the console and rspec tests without any issues. But when I try querying from within the controller, if the file changes (I edit something and save) I get uninitialized constant Admin::Shop::SuggestController::Shop.
To get it to work again I have to restart the server (using Puma).
I get the same behavior when trying to query from other controllers in other namespaces.
There's nothing relevant in the logs.
What am I doing wrong?
Try ::Shop::Product.all.group. That'll cause the constant lookup to begin in the global namespace.
There are a number of good articles written on the subject. Give them a read!

Rails - using namespace controllers to organize files

I am trying to learn about namespacing.
I've asked a few questions on this topic previously, but I'm not understanding what is going on.
I have made a folder in my controller's folder called 'features'. In it, I have saved a file called app_roles_controller.rb.
The first line of that controller is:
class Features::AppRolesController < ApplicationController
The purpose of the features folder is so I can organise my files better (that's it).
In my routes.rb, I have tried:
resources :app_roles, :namespace => "features", :controller => "app_roles"
I have also tried:
namespace :features do
resources :app_roles
end
I have a model (top level) called app_role.rb and I have a views folder saved as views/features/app_roles which then has the index, show etc files in it. The table in my schema is called 'app_roles".
When I rake routes for app_roles, I get:
Paths Containing (app_role):
app_roles_path GET /app_roles(.:format)
app_roles#index {:namespace=>"features"}
POST /app_roles(.:format)
app_roles#create {:namespace=>"features"}
new_app_role_path GET /app_roles/new(.:format)
app_roles#new {:namespace=>"features"}
edit_app_role_path GET /app_roles/:id/edit(.:format)
app_roles#edit {:namespace=>"features"}
app_role_path GET /app_roles/:id(.:format)
app_roles#show {:namespace=>"features"}
PATCH /app_roles/:id(.:format)
app_roles#update {:namespace=>"features"}
PUT /app_roles/:id(.:format)
app_roles#update {:namespace=>"features"}
DELETE /app_roles/:id(.:format)
app_roles#destroy {:namespace=>"features"}
I can't understand what it is that I'm doing wrong.
When I try:
http://localhost:3000/app_roles#index
I get an error that says:
uninitialized constant AppRolesController
When I try:
http://localhost:3000/features/app_roles#index
I get an error that says:
No route matches [GET] "/features/app_roles"
I'm looking for a plain English explanation of how to set this up. I've tried the programming ruby book (several times over).
Please, can you help me understand what needs to happen to introduce organisational files in my rails app?
It looks like your other attempt was actually correct. As outlined in the Rails documentation, if you want to generate routes for the resource app_roles under the namespace features you can add the following to your routes.rb file:
namespace :features do
resources :app_roles
end
Now, you run rake routes you will see the following:
Prefix Verb URI Pattern Controller#Action
features_app_roles GET /features/app_roles(.:format) features/app_roles#index
POST /features/app_roles(.:format) features/app_roles#create
new_features_app_role GET /features/app_roles/new(.:format) features/app_roles#new
edit_features_app_role GET /features/app_roles/:id/edit(.:format) features/app_roles#edit
features_app_role GET /features/app_roles/:id(.:format) features/app_roles#show
PATCH /features/app_roles/:id(.:format) features/app_roles#update
PUT /features/app_roles/:id(.:format) features/app_roles#update
DELETE /features/app_roles/:id(.:format) features/app_roles#destroy
The first line for example means that if you make a GET request to /features/app_roles it will be routed to the index action in the features/app_roles controller.
In other words, if you visit http://localhost:3000/features/app_roles it will route the request to index action that is located in app/controllers/features/app_roles_controller.rb which it expects to have the class Features::AppRolesController.
So your app/controllers/features/app_roles_controller.rb file should look something like this:
class Features::AppRolesController < ApplicationController
def index
end
end

Rails routing gives file not found error

I have a Ruby on Rails application with the following entries in routes.rb:
get '/teachers/welcome', to: 'teachers#welcome'
Which means that if I type: http://localhost:3000/teachers/welcome then I should be able to see the welcome view from the teachers controller. But I keep getting File Not Found error. I'm new to Ruby so bear with me.
When I look at the application, the files are there:
app/controllers/teachers_controller.rb
app/views/teachers/welcome.html.erb
Please watch the naming of you model (without s) but your contoller with s .. and the view name have to match the action name . And run rake routes to check your working routes . + be carefull of the routes order in the routes.rb file .. and will not have any problem in your life with the routes
Assuming that you have a method(action) 'welcome' in your controller try this
get 'teachers/welcome' => 'teachers#welcome'
Make sure you have everything named properly, like the controller and the view.
app/controllers/teachers_controller.rb
class TeachersController < ApplicationController
def welcome
end
end
app/views/teachers/welcome.html.erb
You have to remove the first slash
get 'teachers/welcome' => 'teachers#welcome'
Your Controller:
# app/controllers/teachers_controller.rb
class TeachersController < ApplicationController
def welcome
end
end
Note: you can use a generator to create it automatically:
rails generate controller teachers welcome

Auto-generate routes for scaffolded controller in Rails 4?

I'm trying to get a quick-and-dirty Ajax UI going for an app that already has its data model well in hand - it's basically been managed via rails console so far. Anyway, I thought I would start by auto-generating the missing controller logic that you would get from a rails g scaffold, only instead with rails g scaffold_controller for an existing controller.
It created the controller, and the views, and the assets.. but it didn't touch the routes at all! It didn't even try, didn't say "warning: routes.rb has been modified, not changing" or anything like that, and there's no mention of routes at all in the help output of rails g scaffold_controller.
So how do I say "Just give me the normal routes you would have given me if I started from scratch, please!"?
If I understand the question:
Please, open the config/routes.rb file, and inside the block (routes.draw) add the resources method with the table name (plural of model) as param. Like this:
MyApp::Application.routes.draw do
resources :products
... # rest of code
end
That define the routes for RESTful actions over products. You can read more here
At the console you can run: rake routes to see the available routes at your app.
Although this is asking about Rails 4 for long time ago, but with Rails 5, rails g scaffold_controller still won't auto-generate route, I did it with below monkey patch:
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
patcher = Module.new do
extend ActiveSupport::Concern
included do
hook_for :resource_route, required: true
end
end
Rails::Generators::ScaffoldControllerGenerator.send :include, patcher

Rails Virtual Attributes Not Updating

I have a Model "Tag" that links to the dbpedia article for a particular topic. I want to create a virtual attribute that will use this dbpedia URI to generate a wikipedia URI. Here's roughly what the class looks like:
class Tag < ActiveRecord::Base
# Validation
validates_presence_of :dbpedia_uri, :label
#Virtual Attribute
def wikipedia_uri
"#{dbpedia_uri}".gsub("dbpedia.org/resource", "wikipedia.org/wiki")
end
end
When I go into my console and try to check Tag.all[1].wikipedia_uri, I get the following error:
NoMethodError: undefined method `wikipedia_uri' for #<Tag:0xa0c79ac>
Additionally, I have a second Model (Map) with virtual attributes that do work, but when I change them, I still get the old value. So when the code is:
def thumbnail_uri
"#{map_base_uri}/thumbnails/#{identifier}.jpg"
end
Map.all[1].thumbnail_uri returns something like: "http://WEBSITE/maps/thumbnails/g3201b.ct002662.jpg"
and when I change the code to:
def thumbnail_uri
"test"
end
I still get the output: "http://WEBSITE/maps/thumbnails/g3201b.ct002662.jpg"
I've tried reloading my Rails Console, but it still doesn't seem to be updating the virtual attributes. Any thoughts on what could be causing this issue?
Figured out the issue. I was stupidly running my console in a directory for a duplicate backup set of files, so all of the methods and variables from the backup were available in the console, but my changes to the current code weren't affecting it

Resources