I want to get table name in a model method. I found there should be method table_name but when I try to call it I get NameError Exception: undefined local variable or method `table_name'. It is obviously not there:
pp methods.grep(/^ta.*/)
["table_name_prefix?",
"table_name_suffix?",
"taint",
"taguri",
"taguri=",
"tainted?",
"table_name_prefix",
"table_name_suffix",
"tap"]
How to get a "real" table name (no lowecase - pluralize tricks)?
Thanks
But I need that information in the
model's instance method. How to get
it?
You can simply do this in your instance method:
class Model
def instance_method
puts Model.table_name
end
end
Found it.
It's a class method. Its not so obvious from the Rails 3 documentation.
self.class.table_name
If you are in a class method of the class you want the table name for, try:
class Model < ActiveRecord::Base
def self.class_method
puts self.table_name
end
end
If you try using
self.class.table_name
you'll run into a NoMethodError: undefined method 'table_name' for Class:Class
Related
I want to add a new class method to Mongoid::Criteria, all models can use this method, for example:
class User
include Mongoid::Document
......
end
then I add below code to rails initialize
class Mongoid::Criteria
def use_master
read(mode: :primary_preferred)
end
end
but it doesn't work:
pry(main)> User.use_master
NoMethodError: undefined method `use_master' for User:Class
How to add the "use_master" method to model? Any help in advanced!
Read preference can be changed via persistence context:
User.with(read: {mode: :primary_preferred}) do
# ...
end
This is explained in more depth in Mongoid manual: https://docs.mongodb.com/mongoid/master/tutorials/mongoid-persistence/#runtime-persistence-options
I found a good solution:
module Mongoid
module Findable
def use_master
read(mode: :primary_preferred)
end
end
end
When creating models for the sequel database gem in ruby a syntax like this is used:
class Users < Sequel::Model(:users) # <= what method is getting called here?
# other stuff...
end
Where :users is the name of the table.
I would like to pass an argument to the base class like this when the child class is defined for one of my own classes, but I can't work out how to do it. I don't know what this syntax is called, and I couldn't find any examples of it in my googling. I tried looking at the source for Sequel::Model as well, but its such a big class I couldn't find the relevant section.
Does anyone how what this syntax is and how it works?
It's a common trick to make a normal class/module method call look like a parameterized type.
There is actually a module method Sequel::Model which takes a single argument and returns a class (see the source code).
Have you considered using the #inherited hook of Class?
http://ruby-doc.org/core-2.0.0/Class.html#method-i-inherited
From the docs in the link above:
class Foo
def self.inherited(subclass)
puts "New subclass: #{subclass}"
end
end
class Bar < Foo
end
class Baz < Bar
end
I want a class to return its own name, pluralized, using e.g. "active_support/inflector":
describe "self.resource" do
it "should be databases" do
Database.resource.should equal "databases"
end
end
class Database
def self.resource
self.class.to_s.tableize
end
end
This fails with:
expected #<String:84017460> => "databases"
got #<String:84018030> => "classes"
How can I access the name of the class a singleton method is being called on?
This should work:
class Database
def self.resource
to_s.tableize
end
end
The problem is you call to_s on the class Database belongs to, and it's Class class. You should call to_s on local self instead, which is Database itself. Since self is default receiver of the message, it's okay to leave simply to_s.tableize.
You shouldn't call class method on self. Singleton class already belongs to the class, not the instance.
In your case:
self.to_s.tableize
should work as intended.
I have code like this.
class User < ActiveRecord::Base
end
module Foo
class User
end
end
module Foo
class DoesSomethingWithActiveRecordUser
def initialize user_id
User.find(user_id)
end
end
end
If I call Foo::DoesSomethingWithActiveRecordUser.new(1) I get an error message that says something like undefined method 'find' for Foo::User.
How do I call the ActiveRecord User from within Foo?
Thanks.
Like this:
::User.find(user_id)
Given the following ActiveRecord model:
class User < ActiveRecord::Base
has_many :games
def name
"Joe"
end
def city
"Chicago"
end
end
I'd like to retrieve a list of the methods I added directly to the User class (and not those added by extending ActiveRecord and/or adding associations). Example output:
["name","city"]
Calling User.instance_methods(false) returns method added by ActiveRecord:
["validate_associated_records_for_games", "games", "game_ids", "games=", "game_ids=", "after_create_or_update_associated_records_for_games", "before_save_associated_records_for_games"]
Along with any model attributes from database columns. I'd like to exclude those and just get the custom methods on the subclass.
My purpose is method tracing: I'd like to trace my custom methods while excluding those added by ActiveRecord.
Any ideas?
User.instance_methods - ActiveRecord::Base.instance_methods #=> [:name,:city]
UPDATE:
the order of these methods are significant
class User < ActiveRecord::Base
def self.my_own_methods
self.instance_methods - ##im
end
has_many :games
##im = self.instance_methods
def name
"Joe"
end
def city
"Chicago"
end
end
User.my_own_methods #=> [:name, :city]
This one tested and it works
Use a method_added hook which adds method names to a list, and monkey patch Active Record so that methods added by AR are not added to that list.
If you don't want to crack AR open and start poking around, you could also define a "class macro" which defines a method and adds it to the list. For your own custom methods, use the class macro rather than def.
If you're not familiar with what I'm referring to as a "class macro", it's simply a method like this:
class Class
def mydef(name,&block)
(#methods || []) << name
define_method(name,&block)
end
end
Using something like mydef to define methods rather than def is definitely ugly, but it would solve the problem without requiring any monkey-patching.