简体   繁体   中英

How do I call a before_save method from a parent model class?

I have two models :

class Game
  before_save :update_teacher
    teacher
  end

  def update_teacher
    teacher.update_attribute("something", true)
  end
end

class Puzzle < Game
  belongs_to :teacher
end

I have many types of games. When any game is complete, I'd like to update_teacher.

But as you can see, Game does not belong to anyone. It's just where I keep all my global methods for all the games. I would never need to query Teacher.games . Instead, I only need to query Teacher.puzzles , or Teacher.riddles and so on.

It is because of this, that when I come to the before_save method, and I try to call teacher , it will fail because teacher is not associated with game .

So how can I keep my global Game class handling this method and still refer to its child's association?

Also..

I just realized that this before_save might not actually ever be called because it's not the Game model that's updating ( or is it? ). If it isn't..same question, how do I globalize this inherited method properly?

Alternatively..

I will admit that there might be an architectural flaw to how I'm going about my association. Would anyone recommend that I create two associations, or even just one association from Game directly with a game_type . Not sure what would be better or worse.

If every game has a teacher, the belongs_to :teacher should be in the Game class and not in the subclass.

When you add a before_save in the Game and save a Puzzle it will call the before_save from the Game because Puzzle is a game, but Game has no knowlege of :teacher .

Please update your question with a more detailed description of what you want to accomplish and not of the circumstances.

UPDATE

What you can do, is have a method that is called on the parent class and is overridden by the child classes

class A
  before_save :do_x

  def do_x
    raise "Please implement this!"
  end
end

class B < A
   def do_x
     # do what B has to do
   end
end 

Sounds like Game is a good candidate for a ActiveSupport::Concern based Module that's included in your game classes:

# app/models/concerns/game.rb
require 'active_support/concern'

module Game
  extend ActiveSupport::Concern

  included do
    belongs_to :teacher
    before_save :update_teacher
  end

  module InstanceMethods
    def update_teacher
      teacher.update_attribute("something", true)
    end
  end
end

# app/models/puzzle.rb
class Puzzle
  include Game
end

This way belong_to and before_save are sent to Puzzle when Game is included.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM