Conor
Conor

Reputation: 494

Instant RSpec Test-Driven Development How-to Strong parameters error

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:inblock (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:inblock (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:inblock (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:inblock (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:inblock (4 levels) in ' # ./spec/models/location_spec.rb:39:in block (3 levels) in <top (required)>' # ./spec/models/location_spec.rb:39:inblock (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

Answers (1)

Kenrick Chien
Kenrick Chien

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

Related Questions