7

I am always reading about keeping Controllers thin and doing all logic in models. While this makes senses to me for interacting with databases, what about situations where there is no need to for database interactions?

I have a fairly complex module in my app that interact with several different third party APIs. I use ajax calls to my controller, where all the data is gathered from the APIs and then organized. Then it is displayed via the corresponding .js.erb or .html.erb files.

Is this the proper way to handle this kind of situation? I'm new to rails and don't want to get into habit of doing things wrong.

3 Answers 3

8

Models are not just for dealing with database, but for working with data in principle.

As far as we don't know what situations you mean I can just present some situations.

Ajax call for big Math calculating. It is not touching database and even it can be calculating in tableless model.

# in your controller
def calculating
  Calculator.get_integral_log_and_furie params[:data]
end
# in your model
class Calculator
  def self.get_integral_log_and_furie(data)
    ... # multi line code
  end
end

So you can see that you can calculate it right in your controller, but it should be calculated in your model, so it is reusable and clean solution.

Another example is using some virtual attributes. Names. You can store first, second and third name in saparate columns, so you need to join it. You can create privae method in controler, but of course it is bad idea.

class User < AR::Base
  def full_name
    [first_name, second_name, third_name].compact.join(" ")
  end
end

So you can call it everywhere in your project:

@user.full_name
# Peter Jhonson, or mu is too short

And so on and so on

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

Comments

4

Do model logic in models.

  • Maintain associations.
  • Maintain complex attributes.
  • Maintain validations.
  • Represent concepts from the business/industry.

Do controller logic in controllers.

  • Check that a user is authorized to modify a resource.
  • Pull and aggregate data to pass into a view template.
  • Find the right view template.
  • Compose json for the API response.
  • Retry failed saves.

Models do not need to be ActiveRecords. You can do a whole lot with models - the "core" of your appliation - that has nothing to do with persistence. Just don't put controller logic into these models.

Comments

2

That's a good question.

Even if you don't need to use a database, you can still take an OOP / MVC approach to organise your code and wrap your data, logic and behaviour in models.

Code organisation and encapsulation within model objects is still useful & important!

In Rails 3, you can make non-persisting models by including just some of the ActiveModel modules that ActiveRecord contains. For example:

# This class exists as a fairly simple DTO that is not expected to be persisted, but 
# it does have validation, attributes & a hash constructor, just like ActiveRecord models
class MyProduct
  include ActiveModel::Conversion
  include ActiveModel::Naming
  include ActiveModel::Validations

  attr_accessor :title, :quantity

  validates :title, :quantity, :presence => true
  validates :quantity, :numericality => {:greater_than_or_equal_to => 1}

  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end
end

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.