0

I'm trying to make an active record that involves location. I get the longitude from the params, and try to use the Float() method to convert the locationLongitude and locationLatitude from a string to a float, and I get the following error:

undefined method `call' for #<Class:0x007ffead288530>

Here are the params that the method has access to:

{"locationName"=>"Stanford",
 "locationLatitude"=>"37.42839679991957",
 "locationLongitude"=>"-122.17553785073696"}

And this is the method in my controller that attempts to convert the strings into floats and make the query:

def local
  radius = 10;
  @sort = "local"
  @locationName = params[:locationName]
  @locationLongitude = Float(params[:locationLongitude])
  @locationLatitude = Float(params[:locationLatitude])
  @musings = Musing.(:longitude => (Float(@locationLongitude) - radius)..(Float(@locationLongitude) + radius))

 end

Hope you can help. I also tried doing params[:locationName].to_f and that also didn't work.

Thanks, Paul.

3 Answers 3

2

I'd say it's better to move the processing from within your local method to the Musing (or other) model.

In your form - try to namespace your parameters such that it'd have a musing as an outer most one.

<input name='musing[locationName' ...>

In the controller

def local
  # set some vars
  @musings = Musing.search(params[:musing])
end

In the model

def self.search(params)
  radius = 10
  long = params[:locationLongitude]
  lat = params[:locationLatitude]
  return self unless long and lat
  self.where(:latitude => lat.to_f-radius).where(:long => long.to_f-radius)
end

I can see you resolved the issue - but this might help

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

4 Comments

The model should not be concerned with per request params as this would break down the distinction between controller and model made by the MVC pattern. Params are the realm of the controller. You can however create a Decorator for the model which encapsulates it and provides additional functionality like the one you proposed. But passing params to the model directly stinks of an Antipattern.
Care to elaborate with code sample? AR still uses params through the create (et al) - however in Base. the search method would act similarly, but with direct implementation in child.
Rereading your code, most of it is actually be fine here. I'd only make latitude and longitude actual method parameters instead of pulling them from the hash in search. That said, I came to the conclusion that AR models should only be concerned with actual interaction with the database (including validations and associations). All additional business logic should be in wrapper or library classes to have a proper separation on concerns. One example for that is to use Draper (see the Railscast.
Regarding the create and initialize methods of AR::Base accepting a params hash, I think it's often a cause of security issues and is way too "magic" and should be replaced with explicitly assigning attributes. Yes it is more code, but makes the intend much clearer. And when using wrapper classes, this code doesn't even have to be in the controller. Instead it becomes part of your explicitly defined business logic.
1
Please, change 
params[:locationName].to_f
to
params[:locationName].to_s.to_f

Comments

0

The issue was in this line:

@musings = Musing.(:longitude => (Float(@locationLongitude) - radius)..(Float(@locationLongitude) + radius))

I wrote Musing.(...) instead of Musing.where(...)

What a scrub.

Comments

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.