Two Models: An Owner and a Dog:
owner.rb
class Owner < ActiveRecord::Base
  has_one :dog
end
dog.rb
class Dog < ActiveRecord::Base
    belongs_to :owner
end
And here is the schema:
schema.rb
ActiveRecord::Schema.define(version: 123) do
  create_table "dogs", force: true do |t|
    t.string   "name"
    t.integer  "energy"
    t.integer  "owner_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
  add_index "dogs", ["owner_id"], name: "index_dogs_on_owner_id"
  create_table "owners", force: true do |t|
    t.string   "name"
    t.string   "energy"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end
Pretty simple setup.
I want an owner to take his dog for a walk.  When the walk ends, the owner's energy will drop by 5, AND the dog's energy will drop by 20.
Clearly this walk_the_dog action/method, wherever it is going to live, is effecting two objects: an owner object and a dog object (and of course this dog object happens to be associated to this owner).  
I don't know where to put this code.  I know I could simply create an action within the owners_controller.rb, but that seems like a bad idea.  It would look something like this: 
owners_controller.rb
class OwnersController < ApplicationController
    def walk_the_dog
        @owner = Owner.find(params[:id])
        @owner.energy -= 5
        @owner.dog.energy -= 20   # this line in particular seems like bad OO design
        @owner.save
        @owner.dog.save
    end
    ...
 end
As I understand it, objects should only change state for themselves and shouldn't change the state of other objects.  So this appears to be a bad idea because within the owner controller we are changing the state of not just the owner object, but the associated dog object as well.
I have read about services.  It seems like walk_the_dog is an excellent case for a service, because services, as I understand it, allow interactions between objects and state changes for multiple objects.  I just don't know how to do it/implement it.  
Should there be a service object called walk_the_dog?  Should their just be a file within a services directory with a bunch of service methods -- one of which is called walk_the_dog and the owners_controller.rb simply utilizes this method in it's controller?  I don't know what the next step is.
Note: I can see someone saying "who cares if this breaks OO design. Just do it and if it works, it works." Unfortunately this is not an option. The application I am working on now followed that mindset. The application grew very large, and now maintaining it is very difficult. I want to get this situation down for the major redesign of the app.
                        
Here are the few things that I would do if I were to refactor this code:
Writing numbers in your code is a bad thing, either you have defined them as constants like
ENERGY_PER_WALK_FOR_DOG = 20or a better way is to define a field in the table ofDogmodel. This way, it will be much better to manage and assign those values.I'd create a method in
ApplicationControllerclass:In the folder, app/models/concerns, I would write the following module:
And now, your method reduces to the following method: