Laser
Laser

Reputation: 5439

Getting methods that work in controller/views to function in a model, Ruby on Rails

I'm trying to add a string to the user model under a location column, based on the user's location. I have everything setup to the point that I know the value of @city+@state is added to the appropriate column in the correct model. The problem is, it appears that request.location.city and request.location.state function properly in the controller and views, but not in the model.

def add_location
      @city = request.location.city
      @state = request.location.state
      @location = @city+@state
      self.location = @location
    end

When a user is created, rather than creating a string such as "losangelescalifornia", nothing is created. When I define @city = "bob" and @state = "cat", all users created have "bobcat" in the appropriate place. I know then that everything is functioning except these geolocation based methods. So my question is, how would I get these methods (correct me please if that is not what they are) to function in the model, being request.location.city and request.location.state? Many thanks in advance :)

Upvotes: 0

Views: 324

Answers (2)

tsherif
tsherif

Reputation: 11710

I agree with Rudi's approach, mostly, but I'll offer a little more explanation. The concept you're wrestling with is MVC architecture, which is about separating responsibilities. The models should handle interaction with the DB (or other backend) without needing any knowledge of the context they're being used in (whether it be a an HTTP request or otherwise), views should not need to know about the backend, and controllers handle interactions between the two.

So in the case of your Rails app, the views and controllers have access to the request object, while your models do not. If you want to pass information from the current request to your model, it's up to your controller to do so. I would define your add_location as follows:

class User < ActiveRecord::Base

  def add_location(city, state)
    self.location = city.to_s + state.to_s  # to_s just in case you got nils
  end

end

And then in your controller:

class UsersController < ApplicationController

  def create  # I'm assuming it's create you're dealing with
    ...
    @user.add_location(request.location.city, request.location.state)
    ...
  end
end

I prefer not to pass the request object directly, because that really maintains the separation of the model from the current request. The User model doesn't need to know about request objects or how they work. All it knows is it's getting a city and a state.

Hope that helps.

Upvotes: 2

vlain
vlain

Reputation: 712

request variable is not available in the model since it depends on the current HTTP request. You have to pass to model as param.

def your_action
  ...
  @model.add_location(request)
  ...
end

def add_location(request)
  .. 
end

Upvotes: 0

Related Questions