Rails 3 - расширение модели, которая существует в геме или плагине - PullRequest
2 голосов
/ 04 октября 2011

В жемчужине RefineryCMS есть модель Page, которая используется для получения информации из CMS. Модель не определена в вашем текущем приложении, и поэтому вы не можете изменить ее код (если вы не запрыгнули в гем-код).

Есть ли способ изменить методы в существующей модели, не применяя изменения каждый раз при загрузке страницы? Вот что я попробовал:

  1. Model.class_eval

  2. Model.send: включите, MixinThatHasNewMethods

Я также пытался создать новый класс с обновленными методами и надеялся, что он обновит существующий класс.

Есть идеи?

Ответы [ 2 ]

4 голосов
/ 04 октября 2011

Ruby позволяет разработчику "обновлять" любой объект в любое время.

Это означает, что после загрузки Model в RefineryCMS вы можете просто снова открыть класс и обновить его:

class Model
    def new_method(value)
        ...
    end

    def existing_method(*args)
        ...
        super  # refer to the ovewriten method
    end
end

В вашем случае RafineryCMS - это приложение RoR, что означает, что при загрузке сервера код ruby ​​загружается сначала для платформы rails, затем для плагина / плагина RafineryCMS и, в конце концов, для ваших пользовательских библиотек (например, папки lib).

Важным моментом здесь является порядок загрузки кода, модификация должна быть загружена после подлинного кода класса.

То есть в вашей библиотеке или инициализаторах (не очень хорошее место, но это работает) вы должны поместить ваши привычные методы для класса Model.

РЕДАКТИРОВАТЬ: Я снова читал ваш вопрос, и я должен отметить, что вы не правы, вы на самом деле можете изменить класс из гема или плагина.ruby загружает каждый объект в той же области видимости, и все объекты доступны для перезаписи.

В среде разработки RoR перезагружает все классы (кроме случаев, когда cache_classes = false) при каждом запросе.Возможно, что после первого запроса драгоценный камень перезагрузится, и ваши изменения будут потеряны.Позаботьтесь о перезагрузке ваших библиотек после каждого запроса (только в env разработки)

PS: include & class_eval тоже будет работать, важно перезаписать ранее загруженный класс

0 голосов
/ 04 октября 2011

Если я правильно понимаю ваш вопрос, вы можете сделать что-то вроде этого.

Вы можете переопределить модель следующим образом.Допустим, у вас есть следующий класс:

class User
 def name user_name
  p "my name is #{user_name}"
 end

 def age my_age
   p "age - #{my_age}"
 end

end

, затем вы можете вызвать этот класс по:

user = User.new
user.name "sameera"
user.age 30

, и вы получите вывод:

"my name is sameera"
"age - 30"

затемскажем, вы хотите изменить только поведение метода 'name', вы можете пересоздать пользовательский класс и добавить только этот метод следующим образом:

class User
 def name user_name
   p "my modified name #{user_name}"
 end 
end

и все же вы можете вызвать обаследующие методы:

user = User.new
user.name "sameera"
user.age 30

Но на этот раз ваш результат будет:

"my modified name sameera"
"age - 30"

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

**ПРИМЕЧАНИЕ. Обязательно вызовите измененный класс User, прежде чем загружать исходный класс User.

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