Extending ActiveRecord in rails 4.2 - ruby-on-rails

I've followed this guide:
http://guides.rubyonrails.org/plugins.html#add-an-acts-as-method-to-active-record
In fact, I've actually copied the code and put into my app and it doesn't work.
I keep getting undefined method errors.
When I use console, I can check if the module is initialized and it is, but the model that uses the "acts_as" method throws undefined method errors.
Also in console I can call ActiveRecord::Base.send :include, ... explicitly and then it includes the module -- then everything works. But try as I may, I can't get rails to call .send on ActiveRecord::Base at load time.
Any ideas?

Related

Monkey patching a db model class in Rails with Mongoid causes weird behaviour

I am using a development script file to check out new possible ideas. Recently I tried to monkey patch MyDBObject from within that script file.
Assume an empty dev.rb file and add a monkey patch right in the top like so:
class MyDBObject
def test_function
'function works'
end
end
Starting up the pry console and loading the file yields random results.
First I received:
NoMethodError: undefined method `relations' for MyDBObject:Class
Later the script loaded, but I couldn't access the original class any longer:
undefined method `first' for MyDBObject:Class
I noticed that prepending the line:
MyDBObject
right before the monkey patching, the intended functionality is achieved.
This appears to be some sort of lazy loading of the class objects. Can somebody cast some light on this for me please?
Depending on the order in which source files are loaded, you'll either be redefining the entire class, or having your changes replaced.
I highly recommend giving this a read: http://www.justinweiss.com/articles/3-ways-to-monkey-patch-without-making-a-mess/ (TLDR - put your patch in a module and explicitly include it)

Namespace module class methods undefined

I'm trying to use modules for namespacing reasons. I have this file located in my Rails app at /lib/reports/stripe.rb.
module Reports
module Stripe
def self.foo
puts 'i am foo'
end
end
end
In my console, I'd expect to be able to call foo by Reports::Stripe.foo or Reports::Stripe::foo, but I get the error
NoMethodError: undefined method `foo' for Reports::Stripe:Module
What am I doing wrong? Also feel free to let me know if there's a better way to organize the location and namespacing.
All method calls in ruby use the . syntax. Even "module" methods.
> Reports::Stripe.foo
i am foo
You may be receiving the error NoMethodError: undefined method 'foo' for Reports::Stripe:Module if you have added the method after you have started the rails console. Try restarting the console or reloading the file with load 'reports/stripe'.
The file was actually located in /lib/reports/stripe/stripe.rb. It was a mistake I made much earlier, but forgot to fix. Moving the file to /lib/reports/stripe.rb resolved the issue.

How do I call ActiveRecord::Attributes::ClassMethods#columns?

I have an ActiveRecord class MyClass with some fields in the database and which includes this concern:
module Wrapper
extend ActiveSupport::Concern
included do
puts self #=> MyClass
puts self.columns #=> Array of ActiveRecord::ConnectionAdapters::PostgreSQLColumn
end
end
The first time I access this class (e.g. MyClass.first) I get the expected output (as above).
If I try calling MyClass.first a second time then no output appears, and if I run MyClass.columns without including the concern I get:
output error: #<NoMethodError: undefined method 'name' for #<Object:0x007fd1f20d0ef0>>
Can you help me understand what's going on here?
The method in question is ActiveRecord::Attributes::ClassMethods#columns.
I understand that the code in the included block is scoped to the context of the class which makes sense (making this issue more mysterious).
It would also be great if you could:
Let me know how I could have debugged it further (e.g. how do I identify which object it is that doesn't have the 'name' method)?
Point me to any resources / tutorials that explain this concept
I'm running Rails 4.2.0 and Ruby 2.2.0

Access private methods in the rails console

I'm experimenting with n+1 queries in the rails console, but running
> Zombie.include(:brain).all.each do |z| z.brain end
Results in this error:
NoMethodError: private method `include' called for #<Class:0x000000045bf2a8>
Is there anway I can access the include method? A sort of sudo method that gives the console access to all of my application's methods?
I'm fairly sure you want includes there :)
includes comes from ActiveRecord::Base
include comes from Module

undefined method `rspec_reset' with rspec version 2.14

I am trying execute test cases with rspec version 2.14 for which I am getting following error
undefined method `rspec_reset' for
I am trying to use rspec_reset on the class. The same test cases are working with rspec 2.13.1. So is it possible that rspec_reset method is not available after 2.13?
The reset method does not exist in RSpec 2.14.x. Instead, it is a helper method defined inside the spec_helper.rb file for the rspec-mocks project.
module VerifyAndResetHelpers
def verify(object)
RSpec::Mocks.proxy_for(object).verify
end
def reset(object)
RSpec::Mocks.proxy_for(object).reset
end
end
You can see that this method delegates the reset action to the underlying proxy instead of tacking it on to the class definition of the object in question.
Yes, in 2.14, rspec_reset is no longer available on all objects as it was previously, as discussed in https://github.com/rspec/rspec-mocks/pull/250.
Although I can't find any documentation on it, there now appears to be an RSpec class method reset which takes an object as an argument and will effectively "undo" any RSpec operations that have been done to that object.
There's an RSpec "example" at https://github.com/rspec/rspec-mocks/blob/cee433c89125a3984df33c87eb61985613adce9b/spec/rspec/mocks/mock_spec.rb which still uses the rspec_reset in the description of the example, but which now uses the aforementioned reset method to do the reset. In earlier versions of the example, the reset was done with rspec_reset.

Resources