Два приложения с рельсами, совместно использующие папку модели
У меня есть два приложения с рельсами, запускаемые из одной базы данных, одна из которых запускает клиент, а другая - интерфейс администратора.
Оба приложения имеют одни и те же модели, за исключением небольшого количества различий. Это утомительно для меня, чтобы дублировать подавляющее большинство изменений в моделях на оба приложения.
Один из способов для двух приложений использовать одну и ту же информацию о модели состоит в том, чтобы символизировать папку модели из одного приложения в другое, но я не могу этого сделать из-за нескольких различий кода (например, дополнительной проверки на клиенте).
Есть ли простой способ преодолеть различия, чтобы я мог сохранить общий код в одном месте?
Ответы
Ответ 1
svn: внешние или git подмодули - это, безусловно, способ пойти на такую ситуацию.
Конечно, вы захотите проверить их в обоих приложениях, чтобы вы могли поделиться своими модельными тестами или спецификациями. Но помните, что модели часто зависят от плагинов, поэтому вы также захотите поделиться своей папкой с плагинами. И вам, вероятно, нужны одни и те же драгоценные камни и одна и та же версия Rails, поэтому лучше всего поделиться всем продавцом. О, и иногда ваш код в lib изменяет ваши модели, поэтому вы захотите поделиться этим. О, и не забудьте поделиться любой настраиваемой конфигурацией в файлах среды.
И вы захотите, чтобы сервер непрерывной интеграции настроил ваш тестовый пакет на оба приложения, в случае, если изменения в уровне модели в вашем главном приложении прерывают ваше другое приложение.
Но я имею в виду, что после того, как все это будет разработано, svn: externals или git подмодули - это определенно способ пойти на такую ситуацию.
Обновить (несколько лет спустя)
Rails Двигатели, вероятно, являются лучшим вариантом для надежного обмена модельным кодом между несколькими приложениями. Они могут быть выделены и включены в Gemfile
каждого приложения.
Ответ 2
Почему бы не сделать это способом ООП, например. создавая отдельный базовый класс (в отдельном каталоге), а затем наследуя от него в обоих проектах, поэтому различия находятся в унаследованном классе.
Итак, у вас есть
class BaseModel < ActiveRecord::Base
в подкаталоге "common", а затем вы
class AdminBaseModel < Common::BaseModel
в проекте администратора и
class UserBaseModel < Common::BaseModel
вам может понадобиться
set_table_name "basemodel"
поэтому Rails знает, какую таблицу открыть.
Ответ 3
Я работаю над проектом, который имеет аналогичную проблему, и мы использовали svn: externals, чтобы разделить код модели между двумя приложениями.
В основном у вас есть модели в одном проекте svn и используйте внешний в другом проекте для совместного использования кода. Вы можете редактировать код в любом проекте, и он будет обновлен при запуске svn up
в другом проекте.
Что касается Rails и сценариев сборки, то два каталога моделей полностью разделены.
Ответ 4
Да, сопоставьте каталог моделей, но затем добавьте переменную среды в ваш environment.rb для каждого экземпляра. Затем ваши модели могут узнать, какой экземпляр использует его, и включить дополнительные проверки или что нет.
в environment.rb:
APP_INSTANCE = "app1"
в model.rb
validates_length_of :name, :within => 3..100, :if => :is_app_one?
def is_app_one?
APP_INSTANCE == "app1"
end
Ответ 5
Вы можете рассматривать один проект рельсов как драгоценный камень, тогда вы можете использовать его в другом проекте rails, добавив путь модели к своему пути загрузки.
Вот пример, я думаю, вы можете получить его, хотя он написан на китайском языке.
http://mvj3.github.com/2011/09/13/multiple_rails_apps_sharing_models_folder/
Ответ 6
Просто любопытно - почему у вас нет одного приложения с двумя режимами?
У меня есть одно приложение, которое выглядит как один из дюжины различных приложений, заклейменных по-разному и с разной функциональностью, в зависимости от того, какой URL-адрес вы входите и кто вы входите в систему. У моих пользователей есть роли, и я добавил метод ActiveRecord:: Base, который дает вам текущего пользователя. Таким образом, я могу делать такие вещи, как:
MAX_VOLUME = current_user.admin? ? 11 : 10
validates_inclusion_of :volume, :in => 0..MAX_VOLUME # Admins can go to 11!
И в представлениях, например:
<%= render :partial => common_tabs %>
<%= render :partial => admin_tabs if @current_user.admin? %>
Ответ 7
Почему бы не использовать композицию вместо наследования?
У меня есть аналогичная проблема: приложение для администратора и общедоступное приложение с той же базой данных и только некоторые специальные методы для некоторых моделей для одного приложения или другого.
В настоящее время я думаю, что могу создать общее место со многими модулями, где я бы поставил свои методы. Затем я включил модули, которые мне нужны в каждом приложении (в моделях, контроллерах, помощниках...), когда они мне понадобятся. Это место может быть в каталоге lib (обновлено с помощью субмодуля git или svm external) или в камне (обновлено с помощью Bundler или аналогичного инструмента).
Что вы думаете об этом?