Reputation: 494
I have been working my way through this book but the 'Writing ActiveRecord Specifications' required changes with the Rails 4 strong parameters requirement.
I added a location_controller.rb to overcome the strong parameters error
app/controllers/location_controller.rb
class LocationController < ActionController::Base
params = ActionController::Parameters.new(latitude: lat, longitude: long)
end
app/models/location.rb
require 'active_record'
class Location < ActiveRecord::Base
#attr_protected :latitude, :longitude
validates :latitude, :longitude,:presence => true,:numericality => true
R = 3_959 # Earth's radius in miles, approx
def near?(lat, long, mile_radius)
raise ArgumentError unless mile_radius >= 0
#loc = Location.new(:latitude => lat,:longitude => long)
loc = location.new(params)
R * haversine_distance(loc) <= mile_radius
end
private
def to_radians(degrees)
degrees * Math::PI / 180
end
def haversine_distance(loc)
dist_lat = to_radians(loc.latitude - self.latitude)
dist_long = to_radians(loc.longitude - self.longitude)
lat1 = to_radians(self.latitude)
lat2 = to_radians(loc.latitude)
a = Math.sin(dist_lat/2) * Math.sin(dist_lat/2) +
Math.sin(dist_long/2) * Math.sin(dist_long/2) *
Math.cos(lat1) * Math.cos(lat2)
2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
end
end
spec/models/location_spec.rb
require "spec_helper"
require "rspec/its"
require "/home/conor/geo_pictures/app/models/location"
describe Location do
let (:latitude) { 38.911268 }
let (:longitude) { -77.444243 }
let (:air_space) { Location.new(:latitude => 38.911268, :longitude => -77.444243) }
describe "#initialize" do
subject { air_space }
its(:latitude) { should == latitude }
its(:longitude) { should == longitude }
end
describe "#near?" do
context "when within the specified radius" do
subject { air_space }
it { should be_near(latitude, longitude, 1) }
end
context "when outside the specified radius" do
subject { air_space }
it { should_not be_near(latitude * 10, longitude * 10, 1) }
end
end
context "when a negative radius is used" do
it "raising an error" do
expect { air_space.near?(latitude, longitude, -1) }.to raise_error ArgumentError
end
end
end
Gemfile
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.3'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
gem 'rspec-rails', :group => [:test, :development]
gem 'rspec-its', :group => [:test, :development]
# Use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.1.2'
# Use unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano', group: :development
# Use debugger
# gem 'debugger', group: [:development, :test]
the error message I receive is
Failures:
1) Location#initialize latitude
Failure/Error: let (:air_space) { Location.new(:latitude => 38.911268, :longitude => -77.444243) }
ActiveRecord::ConnectionNotEstablished:
ActiveRecord::ConnectionNotEstablished
# ./spec/models/location_spec.rb:11:in block (2 levels) in <top (required)>'
# ./spec/models/location_spec.rb:15:in
block (3 levels) in '
# ./spec/models/location_spec.rb:17:in `block (3 levels) in '
2) Location#initialize longitude
Failure/Error: let (:air_space) { Location.new(:latitude => 38.911268, :longitude => -77.444243) }
ActiveRecord::ConnectionNotEstablished:
ActiveRecord::ConnectionNotEstablished
# ./spec/models/location_spec.rb:11:in block (2 levels) in <top (required)>'
# ./spec/models/location_spec.rb:15:in
block (3 levels) in '
# ./spec/models/location_spec.rb:19:in `block (3 levels) in '
3) Location#near? when within the specified radius
Failure/Error: let (:air_space) { Location.new(:latitude => 38.911268, :longitude => -77.444243) }
ActiveRecord::ConnectionNotEstablished:
ActiveRecord::ConnectionNotEstablished
# ./spec/models/location_spec.rb:11:in block (2 levels) in <top (required)>'
# ./spec/models/location_spec.rb:25:in
block (4 levels) in '
# ./spec/models/location_spec.rb:26:in `block (4 levels) in '
4) Location#near? when outside the specified radius
Failure/Error: let (:air_space) { Location.new(:latitude => 38.911268, :longitude => -77.444243) }
ActiveRecord::ConnectionNotEstablished:
ActiveRecord::ConnectionNotEstablished
# ./spec/models/location_spec.rb:11:in block (2 levels) in <top (required)>'
# ./spec/models/location_spec.rb:29:in
block (4 levels) in '
# ./spec/models/location_spec.rb:30:in `block (4 levels) in '
5) Location when a negative radius is used raising an error
Failure/Error: expect { air_space.near?(latitude, longitude, -1) }.to raise_error ArgumentError
expected ArgumentError, got # with backtrace:
# ./spec/models/location_spec.rb:11:in block (2 levels) in <top (required)>'
# ./spec/models/location_spec.rb:39:in
block (4 levels) in '
# ./spec/models/location_spec.rb:39:in block (3 levels) in <top (required)>'
# ./spec/models/location_spec.rb:39:in
block (3 levels) in '
Finished in 0.01039 seconds (files took 0.80876 seconds to load) 5 examples, 5 failures
Failed examples:
rspec ./spec/models/location_spec.rb:17 # Location#initialize latitude rspec ./spec/models/location_spec.rb:19 # Location#initialize longitude rspec ./spec/models/location_spec.rb:26 # Location#near? when within the specified radius rspec ./spec/models/location_spec.rb:30 # Location#near? when outside the specified radius rspec ./spec/models/location_spec.rb:37 # Location when a negative radius is used raising an error
Adding this to spec/spec_helper.rb
ActiveRecord::Base.establish_connection(:adapter => "sqlite3",
:database => ":memory:")
changes the error to
/home/conor/geo_pictures/spec/spec_helper.rb:1:in `': uninitialized constant ActiveRecord (NameError)
Upvotes: 0
Views: 157
Reputation: 1046
The first error you should fix is: ActiveRecord::ConnectionNotEstablished
. You need to configure a test database in config/database.yml
.
In your spec (spec/models/location_spec.rb
), you only need to have require 'spec_helper'
. The other classes will be autoloaded by Rails.
Finally, strong parameters are not usually specified in that format.
You would specify them like this:
params.require(:location).permit(:latitude, :longititude)
Refer to the documentation here.
Upvotes: 1