Rails дочерний объект, использующий родительский метод вместо его собственного - PullRequest
0 голосов
/ 17 января 2020

У меня есть дочерний класс Vibe::Interaction::SurveyMessage, который наследуется от Interaction. Они совместно используют одну и ту же таблицу, и SurveyMessage идентифицируется как {app: :vibe, kind:"survey"}.

. Контроллер вызывает метод через родительский класс: Interaction.find(param[:id]).refresh

Проблема в том, что даже когда объект является SurveyMessage Object, он использует родительский метод update_message (пустой).

Есть ли способ заставить объект действовать как SurveyMessage Object создание его экземпляра с родительским классом (Interaction)? Или есть способ определить через родительский класс, принадлежит ли объект дочернему классу?

class Interaction < ApplicationRecord
  enum app: [ :praise, :review, :vibe, :atlas, :goals ]
  belongs_to :survey, class_name: 'Survey', foreign_key: :vibe_survey_id, required: false
  serialize :attachments 

  def message
    {
      text: self.text,
      attachments: self.attachments
    }
  end

  def update_message
  end

  def refresh(options = {})
    update_message
    h = self.history << {
            :type => :refresh,
            :timestamp => Time.current.to_s
          }
    update( 
      history: h 
    )
    # Submit code
    message
  end

end
class Vibe::Interaction::SurveyMessage < Interaction
  default_scope -> { where(app: :vibe, kind: "survey") }

  def update_message
    msg = survey.answer(user_id, self, additional_options||{} )
    update( text: msg[:text], attachments: msg[:attachments])
  end

end

Ответы [ 2 ]

1 голос
/ 17 января 2020

Вы можете использовать becomes метод

https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method -i-становится

Если ваши подклассы имеют шаблон

i = Interaction.find_by(id: id)
i = i.becomes("#{i.kind.capitalize}Message".constantize) if i&.vibe? # or in parent class as a method #downcast
i.refresh
0 голосов
/ 17 января 2020

Мне удалось решить это путем создания метода маршрутизатора на родительском Interaction:

  def self.find_child(id)
    i = Interaction.find_by(id: id)
    if i&.vibe? and i.kind=="survey"
      ans = Vibe::Interaction::SurveyMessage.find(id)
    elsif i&.vibe? and i.kind=="partial"
      ans = Vibe::Interaction::PartialMessage.find(id)
    elsif (etc)
      ...
    else
      ans = i
    end
    ans
  end

Это не элегантно, но работает. Если у кого-то есть лучшее решение, о котором я хотел бы услышать.

...