0

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)

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the correct strong parameters code, I applied this fix and copied 'location.rb' 'location_spec.rb' to another working and rspec functioning rails project and it worked. The test database was configured in config/database.yml , I tested it by added a record via Rails Console 'rails c test' and selected all records which showed the successful insert so the rails project must have another bug preventing the rspec test connecting to the DB
@Conor - glad I was able to help. Please accept this answer if it fixed the problem that you were having.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.