Вспомогательные методы для моделей в Rails

Есть ли в Rails подходящее место для вспомогательных методов для моделей? Существуют вспомогательные методы для контроллеров и представлений, но я не уверен, где лучше всего разместить вспомогательные методы модели. Помимо добавления метода в ActiveRecord::Base, которого я бы предпочел не делать.

ОБНОВЛЕНИЕ. Кажется, беспокойство имеет смысл. Вот пример того, что я хочу. Некоторые модели нельзя удалить, поэтому я добавляю обратный вызов, который всегда выдает исключение:

before_destroy :nope
def nope
  raise 'Deleting not allowed'
end

С опасениями, можно было что-то подобное сделать?

class MyModel < ActiveRecord::Base
  include Undeletable
end

module Undeletable
    extend ActiveSupport::Concern

    included do 
      before_destroy :nope 
    end

    def nope
      raise 'Deleting not allowed'
    end
end

Это способ сделать это с помощью Rails?


person at.    schedule 19.03.2015    source источник
comment
Почему бы вам не использовать старый простой модуль Ruby и не смешать его со всеми нужными вам классами?   -  person Marek Lipka    schedule 19.03.2015
comment
Что значит «помощник для модели»? Может быть, вы ищете декоратора?   -  person Rustam A. Gasanov    schedule 19.03.2015
comment
Было бы полезно, если бы вы привели пример, я думаю, тогда люди могли бы посоветовать по соглашению: есть много способов сделать что угодно, но в целом придерживаться соглашения - хорошая идея.   -  person Max Williams    schedule 19.03.2015
comment
Не могли бы вы добавить пример (код), какие методы вы хотите добавить в ActiveRecord::Base.   -  person spickermann    schedule 19.03.2015
comment
Простой старый модуль Ruby имеет смысл, и это то, что я собирался сделать, просто подумал, что есть другой способ сделать это с помощью Rails. Что, я думаю, касается озабоченностей. Я добавил пример.   -  person at.    schedule 20.03.2015


Ответы (2)


Если вы хотите использовать вспомогательный_метод my_helper_method внутри model, вы можете написать

ApplicationController.helpers.my_helper_method

Если вам нужно немного больше гибкости, например, если вам также нужно переопределить некоторые методы, вы можете сделать это:

class HelperProxy < ActionView::Base
  include ApplicationController.master_helper_module

  def current_user
    #let helpers act like we're a guest
    nil
  end       

  def self.instance
    @instance ||= new
  end
end

а затем использовать с

HelperProxy.instance.my_helper_method

Если у вас крепкие нервы, вы также можете попробовать включить ApplicationController.master_helper_module прямо в свой model.

через сообщение: makandracards.

Для справки: http://railscasts.com/episodes/132-helpers-outside-views

person Gagan Gami    schedule 19.03.2015
comment
Я искал то же самое, и я нашел ваш ответ полезным в моем случае. Спасибо :) - person Hetal Khunti; 19.03.2015
comment
@HetalKhunti: Рад слышать, что вы нашли это полезным - person Gagan Gami; 19.03.2015
comment
Я думаю, что при умеренном использовании ApplicationController.helpers.my_helper_method может быть действительно полезным для совместного использования кода между моделями без создания и включения модуля специально для этого. - person Joshua Pinter; 16.07.2018

Если вы спрашиваете, где разместить код, который является общим для нескольких моделей в рельсах 4.2, то стандартным ответом должно быть использование проблем: Как использовать озабоченности в Rails 4

Однако есть несколько хороших аргументов (например, это), чтобы просто использовать стандартные рельсы, модуль включает и расширяет, как предлагает марек-липка.

Я настоятельно рекомендую НЕ использовать вспомогательные методы ApplicationController в модели, так как вы будете импортировать вместе с ним много ненужного багажа. На мой взгляд, это обычно неприятный запах, поскольку это означает, что вы не разделяете элементы MVC и в вашем приложении слишком много взаимозависимостей.

Если вам нужно изменить объект модели, добавив метод, который просто используется в представлении, обратите внимание на декораторы. Например, https://github.com/drapergem/draper.

person ReggieB    schedule 19.03.2015