Understanding Namespacing - ruby-on-rails

When I run my tests I get an error undefined constant Admin::Blog::Category.
The model is defined like so:
module Blog
class Category < ActiveRecord::Base
...
end
end
When i try to call it from my admin controller I get the error. The controller is defined like so:
module Admin
module Blog
class CategoriesController < Admin::AdminController
...
end
end
end
My question is this name-spaced incorrectly or how do I call the Blog::Category model?

You need to call it as ::Blog::Category.all, for e.g. to get all categories inside the controllers. A litle insight how the search will be happening.
module Blog
class Category
#...
end
end
module Admin
module Blog
class Categories
def self.class_name
Module.nesting
end
end
end
end
Admin::Blog::Categories.class_name
# >> [Admin::Blog::Categories, Admin::Blog, Admin]
After this it will search on the toplevel. Let's see 2 examples:
module Blog
class Category
#...
end
end
Category = 12
module Admin
module Blog
class Categories
def self.const_value
Category
end
end
end
end
Admin::Blog::Categories.const_value # => 12
and, now...
module Blog
class Category
#...
end
end
Category = 12
module Admin
Category = 11
module Blog
class Categories
def self.const_value
Category
end
end
end
end
Admin::Blog::Categories.const_value # => 11
Following 2 examples above, this example ofcourse, should throw error :
module Blog
class Category
#...
end
end
module Admin
module Blog
class Categories
def self.const_value
Category
end
end
end
end
Admin::Blog::Categories.const_value
# uninitialized constant Admin::Blog::Categories::Category (NameError)
Read this guide tutorial to understand this topic.
Last to finish:
module Blog
class Category
end
end
module Admin
module Blog
class Categories
def self.const_value
::Blog::Category
end
end
end
end
Admin::Blog::Categories.const_value # => Blog::Category

Related

Route not find - Rails

Rails 3.2
In my controllers/admin/accounts_receivables_contoller.rb, I have:
class Admin::AccountsReceivables < Admin::ApplicationController
def index
...
end
and in one of the views, I have:
= link_to admin_accounts_receivables_path
In my config/routes.rb, I have:
namespace :admin do
resources :accounts_receivables do
collection do
get 'admin_report'
get 'customer_report'
post 'process_invoices'
end
end
end
rake routes, produces:
admin_accounts_receivables GET admin/accounts_receivables(.:format) admin/accounts_receivables#index
However, when I click on the link, I get (in the browser, but no entry in the log file):
uninitialized constant Admin::AccountsReceivablesController
I do not have a corresponding AccountsReceivable model, as I don't need it.
Any ideas?
The class should be named AccountsReceivablesController and you should nest the class explicitly instead of using the scope resolution operator so that it has the correct module nesting:
module Admin
class AccountsReceivablesController < ApplicationController
def index
# ...
end
end
end
When you use the scope resolution operator class Admin::AccountsReceivablesController - the module nesting is resolved to the point of definition which is Main (the global scope) and not Admin. For example:
module Admin
FOO = "this is what we expected"
end
FOO = "but this is what we will actually get"
class Admin::AccountsReceivablesController < Admin::ApplicationController
def index
render plain: FOO
end
end
See The Ruby Style Guide - namespaces.
class Admin::AccountsReceivables < Admin::ApplicationController
should be...
class Admin::AccountsReceivablesController < Admin::ApplicationController

undefined method `table_name' for Post:Module Did you mean? table_name_prefix

I'm building an API with the kollegorna's tutorial.
I used ActiveHashRelation for displays serialiazed arrays properly.
# app/controllers/api/v1/posts_controller.rb
class Api::V1::PostsController < Api::V1::BaseController
include ActiveHashRelation
def index
posts = apply_filters(Post::Post.all, params)
render json: posts, each_serializer: Api::V1::PostSerializer
end
end
The problem is that I have a model Post::Post and the module Post. It's like it can not found the correct model.
# app/models/post/post.rb
class Post::Post < ActiveRecord::Base
validates_presence_of :body
end
# app/models/post.rb
module Post
def self.table_name_prefix
'post_'
end
end
I think it's because of ActiveHashrelation because when I write posts = Post::Post.all it's working. But I can't filter the array.

Rails Controllers in subfolder ActionController::RoutingError (uninitialized constant

I've seen related questions here in StackOverflow, but I still can't make it work.
I'm making an API with subfolders inside controllers, but I keep getting this error:
LoadError (Unable to autoload constant Api::Report::ReportController, expected ...
/controllers/api/report/report_controller.rb to define it):
Or this one:
ActionController::RoutingError (uninitialized constant Api::Report::ReportController):
This is my folder structure:
->controllers
->api
->report
infected_controller.rb
report_controller.rb
# inflected_controller.rb
module Api
class Report::InfectedController < ReportController
def infected
end
end
end
# report_controller.rb
module Api
class ReportController < ApplicationController
def index
end
end
end
And my routes.rb
Rails.application.routes.draw do
apipie
namespace :api do
scope module: 'report' do
get 'infected' => 'infected#infected'
resources :report
end
end
end
module Api
module Report # <============== missing module
class ReportController < ApplicationController
def index
end
end
end
end
Also
module Api
class Report::InfectedController < Report::ReportController
def infected
end
end
end
Try below code
# report_controller.rb
module Api
class Report::ReportController < ApplicationController
def index
end
end
end

Undefined method in ActiveSupport concern

I have a model that extends ActiveRecord::Base and includes a concern:
class User < ActiveRecord::Base
include UserConcern
def self.create_user()
...
results = some_method()
end
end
UserConcern is stored in the concerns directory:
module UserConcern
extend ActiveSupport::Concern
def some_method()
...
end
end
I am getting a run-time error when I try to create a new user by calling the create_user method that looks like this:
undefined method 'some_method' for #<Class:0x000000...>
I have two questions about this:
Why is the some_method undefined? It seems to me that I am properly including it with the statement include UserConcern. Does it have something to do with my User class extending ActiveRecord::Base? Or maybe something to do with the fact that I am calling some_methods() from a class method (i.e. self.create_user())?
Why does the run-time error refer to #<Class:0x000000...> instead of to #<User:0x000000...>?
try it
models/concerns/user_concern.rb:
module UserConcern
extend ActiveSupport::Concern
def some_instance_method
'some_instance_method'
end
included do
def self.some_class_method
'some_class_method'
end
end
end
models/user.rb:
class User < ActiveRecord::Base
include UserConcern
def self.create_user
self.some_class_method
end
end
rails console:
user = User.new
user.some_instance_method
# => "some_instance_method"
User.some_class_method
# => "some_class_method"
User.create_user
# => "some_class_method"
http://api.rubyonrails.org/classes/ActiveSupport/Concern.html

Rails: i have a class method and i want to modify something of the instance

Rails: i have a class method and i want to modify something of the instance
something like this:
class Test < Main
template :box
def test
# here I want to access the template name, that is box
end
end
class Main
def initialize
end
def self.template(name)
# here I have to save somehow the template name
# remember is not an instance.
end
end
that is similar to the model classes:
# in the model
has_many :projects
How do I do it?
EDIT:
class Main
def self.template(name)
#name = name
end
def template
Main.instance_eval { #name }
end
end
class Test < Main
template 6
end
t = Test.new.template
t # t must be 6
You have to bite the bullet and learn ruby meta programming. There is a book on it.
http://pragprog.com/titles/ppmetr/metaprogramming-ruby
Here is one way to do it.
class M
def self.template(arg)
define_method(:template) do
arg
end
end
end
class T < M
template 6
end
t = T.new
puts t.template
There are a few different ways to do this. Here is one:
class Main
def self.template(name)
#name = name
end
end
class Test < Main
def test
Main.instance_eval { #name }
end
end
Main.template 5
Test.new.test
==> 5

Resources