How can I use a model named Collector in a controller? - ruby-on-rails-3

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])

Related

use activerecord to retrieve virtual attributes when using select() with includes() and where()

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.

Querying another model from inside a model created by FactoryGirl

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.

read_attribute_before_type_cast don't seem to work with serialize:

I have the following model in my Rails app that uses serialization with JSON codec. My database columns are of the type 'text'
class Sample < ActiveRecord::Base
serialize :face_detect, JSON
end
When I run the following in the rails console
Sample.first.read_attribute_before_type_cast('face_detect').class
I'm expecting a 'String' class, since I expect 'before_type_cast', also means before serialisation, but instead I get the 'Hash' class. How is this possible?
(using rvm, with ruby-1.9.2-p290 with rails (3.1.3) and postgresql on Mac OSX)
Serialization happens very deeply inside Arel, but I could access the pre-serialized value like this:
#sample.instance_variable_get("#attributes")["face_detect"].serialized_value
For Rails 4:
#attributes['data'].serialized_value

Nested Resource

I would like to display Brand and Subbrand together on a view page. I am getting an error when I try to declare:
class BrandsController < ApplicationController
def index
#brands = Brand.all
#subbrands = #brands.subbrands #error is coming from this line
Error:
undefined method `subbrands' for #<Array:0x9af1898>
I can't seem to get this working, for the life of me!
I originally posted about my problem in this post:
Undefined method
I have tried to put the logic into the controller as above to see if that helps, but I am still getting the error. The details of the models and routing can be found in my original post.
Please help!
#brands is an Array, not a single ActiveRecord object, so you can't call the subbrands association directly on it. Since you're calling Brand.all, and I assume all Subbrand items are associated with a Brand, you might as well just query all of the Subbrand objects separately:
#brands = Brand.all
#subbrands = Subbrand.all
However, if you were trying to only get a subset of the brands, you could do this. (The second line queries all the subbrands that have a brand_id included in #brands).
#brands = Brand.where(...)
#subbrands = Subbrand.where(:brand_id => #brands.collect(&:id))

How do I use after_save_callback_chain?

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.