I am opening rails console session and do:
2.6.3 :048 > ActiveRecord::Base.connected?
=> true
2.6.3 :049 > ActiveRecord::Base.connection_pool.disconnect!
=> []
2.6.3 :050 > ActiveRecord::Base.connected?
=> false
2.6.3 :051 > ActiveRecord::Base.establish_connection(:development)
=> #<ActiveRecord::ConnectionAdapters::ConnectionPool:0x00 ... >
2.6.3 :052 > ActiveRecord::Base.connected?
=> false
2.6.3 :053 > SomeModel.connection
=> #<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter:0x00 ...>
2.6.3 :055 > ActiveRecord::Base.connected?
=> true
$ rails -v
Rails 5.2.3
my config/database.yml file has to be fine, because HTTP requests are working fine.
Why I cant establish connection in rails console this way?
I am asking because I have similar use of establish_connection in one of config/initializers/ file, that is configuring sneakers workers like here and there it is also returning me false on ActiveRecord::Base.connected?
To connect again you can use
ActiveRecord::Base.connect
AR calls establish_connection only once, for ActiveRecord::Base. All subclasses use the one connection.
You can manually call establish connection yourself on some subclasses. This is very convenient for using two databases at once, e.g.
class MyMainUser < ActiveRecord::Base; end
class MyOtherDb < ActiveRecord::Base; end
class MyOtherUser < MyOtherDb; end
MyOtherDb.establish_connection ...
MyMainUser.first # uses default db
MyOtherUser.first # uses other db
You can't do queries that would cross databases though.
To connect you can use ActiveRecord::Base.connection and than you can call Somemodel.first and its should work.
Related
This question already has an answer here:
Rails table_name_prefix is not working as expected
(1 answer)
Closed 1 year ago.
I have this code:
# app/models/ta.rb
module Ta
def self.table_name_prefix
'ta_'
end
end
...
# app/models/ta/article.rb
module Ta
class Article < ActiveRecord::Base
end
end
From the rails console...
# development environment
Loading development environment (Rails 4.1.6)
2.1.3 :001 > Ta::Article.table_name
=> "ta_articles"
2.1.3 :002 >
...
# production environment
Loading production environment (Rails 4.1.6)
2.1.3 :001 > Ta::Article.table_name
=> "articles"
2.1.3 :002 >
Why is this happening?
Add to config/initializers/namespace.rb something like:
require Rails.root.join('app', 'models', 'ta')
should solve your problem.
I have a Ruby on Rails app with an API in lib. Files in lib are autoloaded, and the API is configured in an initializer.
# lib/my_api.rb
module MyApi
extend Configuration
end
# lib/my_api/configuration.rb
module MyApi
module Configuration
attr_accessor :my_setting
def configure
yield self
end
end
end
# config/initializers/my_api.rb
MyApi.configure do |config|
config.my_setting = 'foo'
end
This works in production, but in development the API gets configured when the server is started. After I change some code, the configuration is lost and there are errors because the settings are nil:
irb(main):001:0> MyApi.my_setting
=> "foo"
irb(main):002:0> reload!
Reloading...
=> true
irb(main):003:0> MyApi.my_setting
=> nil
My guess is that in development, the classes are reloaded, but the initializer is not, which means it only gets configured once after starting the server.
Right now I'm duplicating my configuration in lib/my_api.rb, but that's very hacky.
What's a clean solution for this problem?
module MyApi
module Configuration
mattr_accessor :my_setting
def configure
yield self
end
end
end
mattr_accessor is an ActiveSupport macro for creating module level accessors.
Well, until someone comes up with a better solution, I've come up with two workarounds. I went with 2.
Don't autoload the lib directory (meaning don't autoload the API). That means having to restart the server when the API code changes, but solves the problem. That's why configuring gems like this works -- because they aren't autoloaded.
Manually reload the initializer in development at the end of lib/my_api.rb:
load Rails.root.join('config/initializers/smart_meter.rb') if Rails.env.development?
The MyApi constant will be replaced by a new one when Rails autoloads classes. The configuration is still available on the old object:
Loading development environment (Rails 4.2.0)
irb: warn: can't alias context from irb_context.
irb(main):001:0> MyApi.my_setting
=> "foo"
irb(main):002:0> OldMyApi = MyApi
=> MyApi
irb(main):003:0> reload!
Reloading...
=> true
irb(main):004:0> MyApi.my_setting
=> nil
irb(main):005:0> OldMyApi.my_setting
=> "foo"
irb(main):006:0> load Rails.root.join('config/initializers/smart_meter.rb')
=> true
irb(main):007:0> MyApi.my_setting
=> "foo"
Given this definition (using Rails 3.2.13 on Ruby 2.0.0-p195)...
class Food < ActiveRecord::Base
has_many :recipe_foods, foreign_key: :food_id
.reset is not acting as documented (it's supposed to reset the #loaded flag but instead it's re-querying the database and returning results)...
2.0.0-p195 :037 > f = Food.last
Food Load (1.6ms) ...
=> #<Food ...
2.0.0-p195 :038 > f.recipe_foods
RecipeFood Load (9.4ms) ...
=> [#<RecipeFood ...
2.0.0-p195 :039 > f.recipe_foods.reset
RecipeFood Load (10.0ms) ...
=> [#<RecipeFood ...
I suspect some other gem has hijacked the method, but this is what I get from .method ...
2.0.0-p195 :040 > f.recipe_foods.method(:reset).source_location
NameError: undefined method `reset' for class `Array'
How do I figure out what version of .reset is actually executing?
UPDATE:
When I try to call a non-existent method I get this chaos (in case that helps with the mystery):
2.0.0-p195 :052 > f.recipe_foods.snafu
NoMethodError: undefined method `snafu' for #<ActiveRecord::Relation:0x007fdaef6315b0>
2.0.0-p195 :053 > f.recipe_foods.method(:snafu)
NameError: undefined method `snafu' for class `Array'
My guess is that reset is actually a method on the AssociationProxy object, not the Array, which is why you're getting the undefined method. Rails 4 seems to be smarter about this:
> c = Company.first
> c.users.method(:find)
=> # <Method: ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_User(ActiveRecord::Associations::CollectionProxy)#find>
> c.users.method(:find).source_location
=> ["/Users/me/.rvm/gems/ruby-2.0.0-p195/gems/activerecord-4.0.0/lib/active_record/associations/collection_proxy.rb", 140]
I'm not sure of the best solution here, but I'd see if any of the tools in pry can be helpful.
Use a debugger. ruby-debug worked up until Ruby 1.9; byebug works for Ruby 2.0.
Write a script with a debugger breakpoint right before the call that's breaking:
f = Food.last
rf = f.recipe_foods
byebug # or debug
rf.reset
Then execute the script. The debugger will break right at before the call, which you can then step into to find out what code is actually being executed.
In Java I might do:
public static void doSomething();
And then I can access the method statically without making an instance:
className.doSomething();
How can I do that in Ruby? this is my class and from my understanding self. makes the method static:
class Ask
def self.make_permalink(phrase)
phrase.strip.downcase.gsub! /\ +/, '-'
end
end
But when i try to call:
Ask.make_permalink("make a slug out of this line")
I get:
undefined method `make_permalink' for Ask:Class
Why is that if i haven't declared the method to be private?
Your given example is working very well
class Ask
def self.make_permalink(phrase)
phrase.strip.downcase.gsub! /\ +/, '-'
end
end
Ask.make_permalink("make a slug out of this line")
I tried in 1.8.7 and also in 1.9.3
Do you have a typo in you original script?
All the best
There is one more syntax which is has the benefit that you can add more static methods
class TestClass
# all methods in this block are static
class << self
def first_method
# body omitted
end
def second_method_etc
# body omitted
end
end
# more typing because of the self. but much clear that the method is static
def self.first_method
# body omitted
end
def self.second_method_etc
# body omitted
end
end
Here's my copy/paste of your code into IRB. Seems to work fine.
$ irb
1.8.7 :001 > class Ask
1.8.7 :002?>
1.8.7 :003 > def self.make_permalink(phrase)
1.8.7 :004?> phrase.strip.downcase.gsub! /\ +/, '-'
1.8.7 :005?> end
1.8.7 :006?>
1.8.7 :007 > end
=> nil
1.8.7 :008 > Ask.make_permalink("make a slug out of this line")
=> "make-a-slug-out-of-this-line"
Seems to work. Test it out in your irb as well, and see what results you're getting. I'm using 1.8.7 in this example, but I also tried it in a Ruby 1.9.3 session and it worked identically.
Are you using MRI as your Ruby implementation (not that I think that should make a difference in this case)?
In irb make a call to Ask.public_methods and make sure your method name is in the list. For example:
1.8.7 :008 > Ask.public_methods
=> [:make_permalink, :allocate, :new, :superclass, :freeze, :===,
...etc, etc.]
Since you also marked this as a ruby-on-rails question, if you want to troubleshoot the actual model in your app, you can of course use the rails console: (bundle exec rails c) and verify the publicness of the method in question.
I am using ruby 1.9.3 and the program is running smoothly in my irb as well.
1.9.3-p286 :001 > class Ask
1.9.3-p286 :002?> def self.make_permalink(phrase)
1.9.3-p286 :003?> phrase.strip.downcase.gsub! /\ +/, '-'
1.9.3-p286 :004?> end
1.9.3-p286 :005?> end
=> nil
1.9.3-p286 :006 > Ask.make_permalink("make a slug out of this line")
=> "make-a-slug-out-of-this-line"
It's also working in my test script. Nothing wrong with your given code.It's fine.
I've tried most of the solutions such as require_dependency, adding autoload in application.rb, and enabling the lib folders but still no dice.
Here's how my application is set up:
I have in lib/index_tank_searcher.rb:
class IndexTankSearcher < Spree::Core::Search::Base
def method
end
end
And I have Spree::Config.searcher_class = IndexTankSearcher in config/intializers/spree.rb.
Any ideas on how to make sure that index_tank_searcher.rb auto reloads without restarting the server each time it changes?
Reloading classes doesn't mutate existing classes. Classes to be unloaded are unassigned from their constant and a fresh copy is assigned. This is easily verifiable in the console
1.9.3p194 :002 > User.object_id
=> 70274894338560
1.9.3p194 :003 > reload!
Reloading...
=> true
1.9.3p194 :004 > User.object_id
=> 70274935456220
However Spree::Config.searcher_class is still set to the original IndexTankSearcher class.
You could add a to_prepare callback that will be called on each request in development, but only once (on startup) in production