The main documentation describe it at debugging callbacks but it seems to not exists:
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
I've tried to use just like the example and it returns me:
ruby-1.8.7-p330 :026 > Device.after_save_callback_chain
NoMethodError: undefined method `after_save_callback_chain' for #<Class:0x104bc1060>
from /rvm/gems/ruby-1.8.7-p330/gems/activerecord-3.0.5/lib/active_record/base.rb:1008:in `method_missing'
from (irb):26
Seems like this method has disappeared in Rails 3. I've used the following before :
Model._save_callbacks.select { |callback| callback.kind.eql?(:after) }
This will get you any after_save callbacks. You can then get further information like the proc that's being called by checking the .filter attribute :
Model._save_callbacks.select { |callback| callback.kind.eql?(:after) }.collect(&:filter)
Hopefully someone has a nicer answer than this though.
This _#{kind}_callbacks method is defined on ActiveSupport I think so you can do similar stuff with controllers and whatnot I'd assume.
Related
I'm having trouble retrieving virtual attributes when making database queries. The following works as expected:
s = Story.includes(:scenes).select("stories.*, 3 as testval")
s.first.title
=> "My Story"
s.first.testval
=> 3
But when I put in a where clause, it stops working:
s = Story.includes(:scenes).select("stories.*, 3 as testval").where("scenes.id < ?",1000).references(:scenes)
s.first.title
=> "My Story"
s.first.testval
NoMethodError: undefined method `testval' for #<Story:0x007fcd6b93eb68>
I'm guessing the issue is that ActiveRecord doesn't know that 'testval' should belong to 'stories' instead of 'scenes', but I'm not sure. Does anyone know how to resolve this?
Sorry to be the bearer of bad news but you can't do a custom select and eager load as references/eager_load overrides the select with a bunch of t%d_r%d.
You'll need to do approach with a different ActiveRecord strategy if you need virtual attributes.
I'm trying to do this in my controller:
#collector = Collector.find(params[:id])
But when I do, I get this error:
undefined method `find' for ActionController::MimeResponds::Collector:Class
How can I show that I'm trying to use the ActiveRecord model named Collector?
Try to refer to the class prefixed by :: as in ::Collector
Try: Collector::find(params[:id])
On my site, moderators can flag spammy comments. When these comments are flagged, they get quarantined so they no longer appear in regular views, though they can still be seen in the administrative control panel. At the moment, I exclude them from regular views like so:
#comments = Comment.where(:flagged => false)
I do this in every controller that has comments in it, of which there are many. I get the feeling that there's a cleaner way to handle this in Rails. Perhaps somewhere in the comments model I can specify that when querying for comments, only retrieve those that aren't flagged. If so, how is that done? And even if that's not possible, is there some other way to dry this code?
u can use a default scope
default_scope where(:flagged => false)
see http://apidock.com/rails/ActiveRecord/Base/default_scope/class
the default scope can be ignored using unscoped. See http://apidock.com/rails/ActiveRecord/Base/unscoped/class
i would prefer using a scope rather a default scope since i dont have to override it when all the records are needed. Depends upon the frequency of fetching all/unflagged records.
Make a scope (named 'clean' for this example):
class Comment < ActiveRecord
scope :clean, where(:flagged => false)
end
Then use:
#comments = Comment.clean
For future-proofing, you may may want to add a class method called default_view which just calls clean and use that instead. As your 'default' needs change, just modify the default_view method.
I've just started using this and immediately ran into a problem mapping a parameter to a a constructor parameter.
I've tried every example I can find on SO but none seem to work and the documentation doesn't mention this feature as far as I can see.
The examples show:
Mapper.CreateMap<UserProfile, UserProfileModel>().ConstructUsing(x => new UserProfileModel(x.Id);
I can't figure out the syntax to get access to the Id property on the UserProfile object.
Another example shows:
Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing((Func<ResolutionContext, TypeOne>) (r => new TypeOne()));
On using any of these lambdas I just have access to the ResolutionContext not the parent object?
Any Ideas?
Just starting with FactoryGirl. I have a Model named Subscription. It has a method 'set_price` which apparently does some calculations. In order to do so, it has to ask another model for some values:
def set_price
base_price = Option.find_by_key(:base_price).value.to_f
# […] some calculations
end
When running my specs I get:
NoMethodError:
undefined method `value' for nil:NilClass
Which is quite logical since I didn't (yet?) create any Options.
Is FactoryGirl suited for this? Do I have to create Option fixtures in this case? Or just mock it?
This will fail because there are no Options in the database. You can either create the option factory before calling set_price in the test (you'll need to make sure find_by_key(:base_price) will return your factory created option in this case), or you can as you say use a mock:
option = mock_model('Option', :value => 1)
Option.stub(:find_by_key).and_return(option)
The mock has the advantage that it will not touch the database, but it's potentially more brittle.