ActiveRecord::AssociationTypeMismatch ruby 1.8 without using spork - ruby-on-rails-3

I have models specs, controllers spec and request spec. When I run:
rspec spec
models spec are run first, then request and then when controller specs are run the specs for the first controller are OK, but the next fail. But when I run only the controller specs they all pass. I am with rails 3.0.9, ruby 1.8, factory_girl 2.2.0. I have
config.cache_classes = true
in test.rb and I can't change the version of ruby or factory_girl. Can someone help me?
UPDATE:
This is the error:
96) UsersController reset_password: as non-master_admin: does not reset a user's password
Failure/Error: let!(:user) { Factory(:admin_user) }
ActiveRecord::AssociationTypeMismatch:
AdminUser(#-630697398) expected, got MerchantUser(#-629918188)
# ./app/models/activity.rb:33:in `log'
# ./config/initializers/add_activity_logging.rb:8:in `_callback_after_759'
# ./spec/controllers/users_controller_spec.rb:8
in spec/controllers/users_controller_spec.rb:8:
let!(:user) { Factory(:admin_user) }
in activity.rb:33:
create(:user => user, :title => title, :changeable_id => changeable.id,
:changeable_type => changeable.class.to_s, :data => attributes)
also there is:
belongs_to :user, :class_name => 'AdminUser'
in the class AdminUser there isn't has_many activities but when I tried to add it I couldn't add it correctly I guess.
Thanks for the help
UPDATE:
AdminUser and MerchantUser are descendants of User
POSIBLE FIX
The line that gave error was actually:
admin_user = Factory(:tech_admin)
I replaced it with:
admin_user = FactoryGirl.build_stubbed(:tech_admin)
This way the file activity.rb is not reached
FINAL FIX
Apparently the problem was with Factory(:reseller). I replaced it with FactoryGirl.create(:reseller) and it everything work. Though now I am wondering and searching what is the difference between the two uses

Related

rspec vs 'url_validation' gem

I'm struggling with rspec as a new Rails person and I have a need to validate a url passed into Active Record. This is probably due to my ignorance so pls point me in the right direction. The video_url is a string field which I'd like to validate as being a valid URL. Looking around, I chose this gem because it appeared to be fully tested in rspec. For my test I didn't see how I could incorporate his validation test into my model test.
In rails console, I created a Post object and ensured that if I put a bogus URL that I knew would not be found, I would get an error. The curious thing is that attempting to replicate this in a test with the gem installed fails the test because it finds no errors. I expected an error of some kind as I got in console. My question is what am I doing wrong in that it gets no errors? I've made several attempts to triangulate what might be causing it but the gem doesn't seem to work in rspec? I would have thought that if I could get it to work in console, I can get it to work in rspec?
post.rb
class Post < ActiveRecord::Base
attr_accessible :body, :title, :image, :video_title, :video_url
validates_presence_of :title, :body, :author
validates :video_url, :presence => true, :if => :video_title_present?, :url => {
:check_path => [ 300..399, 400..499, 500..599 ], :allow_nil => true,
:url_not_accessible_message => "must be valid.",
:invalid_url_message => "must be valid.",
:url_invalid_response_message => "must be valid."}
def video_title_present?
!self.video_title.blank?
end
belongs_to :author, class_name: "User"
end
post_spec.rb
before do
#post = Post.new(title: "foo", body: "my body here")
end
describe "validates with video links" do
it "validates with video url and video title" do
#post.video_url = "http://heckitoqi.com"
#post.video_title = "my title"
#post.should have_at_least(1).error_on(:video_url)
end
end
Output in console:
Failure/Error: #post.should have_at_least(1).error_on(:video_url)
expected at least 1 error on :video_url, got 0
In some of my errors, I attempted a more open-ended error, but it fails by not catching any errors.
Here is a short version of my smoke test of the model using Rails console:
u = User.first
p = Post.new(title: "title", body: "body", video_title: "vtitle", video_url: "http://heckitoqi.com")
p.author = u
p.save!
>> HTTPI GET request to heckitoqi.com (net_http)
>> ActiveRecord::RecordInvalid: Validation failed: Video url must be valid.
If I can get it to validate in the console, then my implementation of the test is at fault, right? I just don't see what I'm doing wrong. thanx, sam

Setting Devise omniauth_path_prefix doesn't work

I'm working on a Rails-based API. I recently started attempting to version it. (I'm using the Versionist gem, in case it matters) One version ('v2') uses Devise and Omniauth to authenticate users through Facebook/Twitter.
I want all the routes associated with this version to have the appropriate version prefix (so users/:username/foo becomes v2/users/:username/foo, etc.), but I've already found out that putting devise_for inside the api_version block prevents the Devise helpers (current_user, user_signed_in?, etc.) from working, so it continues to live outside the block:
routes.rb:
devise_for :user, :path => '', :controllers => {:omniauth_callbacks => 'users/omniauth_callbacks'}, :skip => [:registrations, :confirmations, :sessions, :passwords]
api_version(:module => "V2", :path=>"v2") do
resources :authentications, :only => [:update, :destroy]
devise_scope :user do
post 'login' => 'sessions#create', :as => 'user_session'
get 'logout' => 'sessions#destroy'
post 'password' => 'devise/passwords#create'
put 'password' => 'devise/passwords#update'
end
end
Everything seemed great... except the Devise-generated omniauth routes:
rake routes output:
user_omniauth_authorize /auth/:provider(.:format)
user_omniauth_callback /auth/:action/callback(.:format)
Now, some google-fu revealed that there's a devise configuration setting for this, so I added the following to our devise initializer (config/initializers/devise.rb):
Devise.setup do |config|
config.omniauth_path_prefix = 'v2/auth'
end
Now, rake routes produces paths that look sensible:
user_omniauth_authorize /v2/auth/:provider(.:format) v2/users/omniauth_callbacks#passthru {:provider=>/(?!)/}
user_omniauth_callback /v2/auth/:action/callback(.:format) v2/users/omniauth_callbacks#(?-mix:(?!))
However, when I attempt to access this route by calling api.localhost/v2/auth/facebook, I get a routing error:
ActionController::RoutingError (No route matches [GET] "/v2/auth/facebook")
Any idea what's going on here?
You are missing the provider name in the routes so they don't match the facebook part in /v2/auth/facebook. The correct route destination should look something like v2/users/omniauth_callbacks#(?-mix:facebook).
Have you specified the provider in the user model?
devise_for ..., :omniauthable, :omniauth_providers => [:facebook]
For the record, I'm using Rails 3.2 and Devise 3.0 and the altered route seems to work (I haven't gone further yet to see if something else will break).

How do I invoke liquid-rescale with the Paperclip gem?

I'm using the Paperclip gem with a Rails 3.1.1 app. It's working as advertised and expected. I would like to use the imagemagick -liquid-rescale delegate, however. According to the imagemagick documentation (which I tried in terminal.app), this works:
convert logo_trimmed.jpg -liquid-rescale 75x100%\! logo_lqr.jpg
I tried a variation...
convert my_pic.jpg -liquid-rescale 60x60\! my_new_pic.jpg
That worked as expected, too. I've tried several permutations in my Image model in my rails app, but I cannot get Paperclip to invoke liquid-rescale. My latest attempt was:
has_attached_file :pic, :styles => {:square => "-liquid-rescale 60x60\!" }
This fails without an error message, merely duplicating the original image with a new name.
How do I instruct paperclip to invoke liquid-rescale?
Here's what I did. I had to write a custom processor, which I named liquid.In the model:
has_attached_file :pic, :styles => {:square => {:processors =>[:liquid],:geometry => "60x60>"} }
I'm not sure whether the :geometry option is necessary, but I added it because thumbnail.rb in the paperclip gem says that it's not optional.
I then added a file: /my_app/lib/paperclip_processors/liquid.rb with contents:
module Paperclip
class Liquid < Thumbnail
def transformation_command
"-resize '60x60>' -liquid-rescale '60x60!'"
end
end
end
Finally, I ran the following in the console:
Image.all.each {|i| i.pic.reprocess!}
That did the trick.

Formtastic ~> 2.0.2 and enumerated_attribute gem, Rails 3.1.1

I used enumerated_attribute with formtastic ~> 1.2.3 with "monkey patch" for field :as => :enum and everything worked fine.
But when I updated formtastic to 2.0.2 version appeared an error with message "Formtastic::UnknownInputError".
For more details here is patch, that was added to /initialisers/formtastic.rb:
module Formtastic #:nodoc:
class SemanticFormBuilder #:nodoc:
def enum_input(method, options)
unless options[:collection]
enum = #object.enums(method.to_sym)
choices = enum ? enum.select_options : []
options[:collection] = choices
end
if (value = #object.__send__(method.to_sym))
options[:selected] ||= value.to_s
else
options[:include_blank] ||= true
end
select_input(method, options)
end
end
end
P.S. I tried to change SemanticFormBuilder to FormBuilder (as I understood from new formtastic documentation there was such change for all custom inputs), but I was still getting error
Maybe anybody already used these gems together successfully?
They way custom fields are defined has changed completely in Formtastic 2.x
You need to subclass the internal Formtastic classes to get what you want. A select input would look something like this:
module FormtasticExtensions
class EnumeratedInput < Formtastic::Inputs::SelectInput
def collection
# programmatically build an array of options in here and return them
# they should be in this format:
# [['name', 'value'],['name2', 'value2']]
end
end
end
Include the module in the Formtastic initializer:
include FormtasticExtensions
and this will give you a field :as => :enumerated and you should be good to go. In my case (some other custom field) it selects the current option, but you may need to tweak the code for yours to work.
You could also just pass the collection in:
f.input :thing, :as => :select, :collection => your_collection, :label_method => :your_name, :value_method => :your_id

NoMethodError - undefined method

I'm having problems displaying data from a separate controller. I have a number of users, each with many pages. I've followed this tutorial with a few minor adjustments.
The error that keeps appearing is:
NoMethodError in SitesController#show
undefined method `page' for #<ActionDispatch::Request:0x00000102452d30>
My routes.rb is as follows:
devise_for :users
resources :users, :only => [:index, :show] do
resources :pages, :shallow => true
end
match '/' => 'sites#show', :constraints => { :subdomain => /.+/ }
root :to => "home#index"
And I have a sites controller:
class SitesController < ApplicationController
def show
#site = Site.find_by_name!(request.page)
end
end
I've also tried:
def show
#site = Site.find_by_name!(params[:site])
end
Which gives a different error.
Am totally stuck trying to figure this out!
Looking forward to your assistance.
Bob
The problem is here: request.page
The request object is of the class ActionDispatch::Request, which does not have a page method.
To track down errors like this, you can try either looking at the docs or messing around in the debugger.
Try running your controller with --debugger enabled.
If you are running Ruby 1.8, install the ruby-debug gem.
If you are running Ruby 1.9, install the ruby-debug19 gem.
Add a debugger call here:
class SitesController < ApplicationController
def show
debugger
#site = Site.find_by_name!(request.page)
end
end
Run your server with the --debugger option.
See what p request.page does. I bet it will have an "undefined method" error, just you see when you try to view that controller action.
If you do a p request.class you can find out what class the object is, and then look up the docs to see how to use it.