Как определить обработчик типа rescue_from для моделей ActiveRecord? - PullRequest
0 голосов
/ 26 марта 2019

Разработка в Rails 5.2.2.1. Я хочу определить «глобальный» обработчик спасения для моей модели, чтобы я мог поймать NoMethodError и предпринять соответствующие действия. Я считаю, что контроллеры могут сделать это с rescue_from, но модели не могут. Зная, что разработчики Rails - умные люди;) Я полагаю, что для этого должна быть веская причина, но я все еще разочарован. Погуглив, я даже не могу найти примеров, когда люди спрашивают, как это сделать, и другие люди либо говорят им, как, или почему они не могут, либо почему они не должны этого хотеть. Может быть, это потому, что обработчики спасения не могут вернуть значение исходному вызывающему объекту?

Вот что я пытаюсь сделать: мне нужно провести рефакторинг своего приложения, чтобы то, что раньше было единой моделью, теперь делилось на две (назовем их Orig и New). Вкратце, я хочу сделать так, чтобы при вызове метода получения атрибута (скажем) для объекта Orig, если этот атрибут переместился в New, я мог поймать эту ошибку и вместо этого вызвать new.getter (понимая, что Orig сейчас belongs_to новый). Это решение основано на моем опыте работы с такими возможностями Perl5 AUTOLOAD.

Любые идеи о том, как это сделать, очень ценятся. Может быть, мне просто нужно определить геттеры / сеттеры для всех перемещенных атрибутов индивидуально.

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Очевидно, что мне нужно было знать слово " делегирование ". Кажется, в Ruby и Rails существует множество способов сделать подобные вещи, и я должен был ожидать, что в Ruby это будет чище, элегантнее и более развито, чем в Perl5. В частности, последние версии Rails предоставляют « делегат_missing_to », что, как представляется, именно то, что мне нужно для этого варианта использования.

0 голосов
/ 26 марта 2019

Overide method_missing :)!?

Вы можете попробовать переопределить метод method_missing. Это может привести к сбивающим с толку ошибкам, но переопределение этого метода определенно используется для, по крайней мере, одного драгоценного камня, о котором я знаю.

Я не хотел вызывать класс new, потому что это зарезервированное ключевое слово и может привести к путанице. Поэтому я изменил имя класса на Upgraded.

Это должно помочь вам начать.

class Upgraded
  def getter
    puts "Congrats, it gets!"
  end
end

class Original
  def initialize
    @new_instance = Upgraded.new
  end

  def method_missing(message, *args, &block)
    if message == :attribute_getter
      @new_instance.send(:getter, *args, &block)
    else
      super
    end
  end

  def respond_to_missing?(method_name, *args)
    method_name == :attribute_getter or super
  end
end

c = Original.new
c.attribute_getter
  • Вам придется изменить имена методов получения и установки. Поскольку у вас есть belongs_to ассоциация, вы можете просто использовать это.

Или вы можете попробовать просто использовать Delegate_to

как подсказывает @mu_is_too_short, вы можете попробовать что-то вроде этого?

class Original < ApplicationRecord
 belongs_to :upgraded
 delegate :getter_method, :to => :upgraded 
end

class Upgraded < ApplicationRecord
  def getter_method
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...