Rails model name lookup: strange uninitialized constant error - ruby-on-rails

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!

Related

Uninitialized constant error when trying to refer to a database record within a service

I'm trying to create a rake task that uses a service. Within that service, I want to load the last saved record of a MonthlyMetrics table within my database.
Within my rake file:
require 'metrics_service'
namespace :metrics do
#metrics_service = MetricsService.new
task :calculate_metrics => [:check_for_new_month, :update_customers, :update_churn, :do_more_stuff] do
puts "Donezo!"
end
# ...more cool tasks
end
And my MetricsService within lib/metrics_service.rb:
class MetricsService
def initialize
#metrics = MonthlyMetric.last
#total_customer_count = total_customers.count
assign_product_values
end
# Methods to do all my cool things...
end
Whenever I try to run something like rake:db:migrate, I get the following error:
NameError: uninitialized constant MetricsService::MonthlyMetric
I'm not sure why it's trying to refer to MonthlyMetric the way it is... As a class within the MetricsService namespace..? It's not like I'm trying to define MonthlyMetric as a nested class within MetricsService... I'm just trying to refer to it as an ActiveRecord query.
I've done other ActiveRecord queries, for example User, in other services within the same directory.
What am I doing wrong here?
I think if you just add => :environment to the end of your rake task, that may fix the problem.
As in:
task :calculate_metrics => [:check_for_new_month, :update_customers, :update_churn, :do_more_stuff] => :environment do
I've run into similar problems where Rails does not initialize the correct environment without this tacked on to each rake task.

Ruby on Rails - Active Admin: Conflict with a Global Variable

On Rails 4 with the latest version of Active Admin (using Ransack). I have an Award model that I made available globally in my application_controller.rb:
before_action :set_awards
private
def set_awards
#awards = Award.all
end
This is so I could have a global navigation dropdown listing all awards (on the public side). I think this is conflicting with Active Admin. When I went to the Awards index page, I got the following error message:
Collection is not a paginated scope. Set collection.page(params[:page]).per(10) before calling :paginated_collection.
I am not sure what this means exactly but since this is the only model this happens to, I'm guessing it has something to do with my code in the app controller. I think my problem is similar to this question:
Rails 3.2 ActiveAdmin 'Collection is not a paginated scope.' error
...I would prefer not to change the model's label and the metasearch code provided doesn't work because (I think) Active Admin now uses Ransack. Thanks for any help.
I have had the same problem and it was a variable name i was declaring at the application controller that was conflicting with the ActiveAdmin.
I have a model called Post and in my applicationController i had a method like this:
def load_posts
#posts = Post.all
end
It returned me the error you mention, so i fixed it changing the variable name to:
def load_posts
#post_list = Post.all
end
Hope it helps.
May be you overwrited a local variable #awards in ApplicationController, but Active Admins is inheriting from the application controller.
Just rename your variable and it will run.

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

What is causing a NoMethodError '_view_paths' exception?

First off, the exception in question:
undefined method '_view_paths' for nil:NilClass`
The related routes:
get 'payments/index' => 'payments#index'
get 'payments/class' => 'payments#class'
get 'payments/kids' => 'payments#kids'
get 'payments/donate' => 'payments#donate'
The associated controller:
class PaymentsController < ApplicationController
def index
end
def class
end
def kids
end
def donate
end
end
So, the exception occurs every time I try to access one of the routes. The views for the routes described above are the simple ones generated with scaffolding and use no other rails API calls. I can't seem to find any other information on this '_view_paths' method. The only assumption I can make thus far is that the proper view isn't being found, but all views reside exactly where expected according to rails conventions (app/views/payments/*).
Has anyone stumbled upon this issue and found a solution?
You can't define a method named "class" as it's already a reserved method to refer to the object's class, for example:
Object.new.class #=> Object
Technically I suppose you can override it (as you have), but doing so is mostly likely going to have some bizarre consequences unless you know what you're doing.
The error is probably happening when the code tries to call something like self.class._view_paths. It expects to be calling PaymentsController._view_paths. However, you've overridden the instance method class with an empty method returning nil, hence the nil exception.

Rails routing error with long class names

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"

Resources