Два рельса приложения, совместно использующие папку модели - PullRequest
22 голосов
/ 19 марта 2009

У меня есть два приложения rails, работающие с одной и той же базой данных, одно из которых запускает клиент, а другое - интерфейс администратора.

Оба приложения имеют одинаковые модели, за исключением небольшого количества различий. Мне утомительно дублировать подавляющее большинство изменений в моделях обоих приложений.

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

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

Ответы [ 7 ]

6 голосов
/ 21 января 2011

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

Итак, у вас есть

class BaseModel < ActiveRecord::Base

в «общем» подкаталоге, и тогда у вас есть

class AdminBaseModel < Common::BaseModel

в админ-проекте и

class UserBaseModel < Common::BaseModel

вам может понадобиться

set_table_name "basemodel"

чтобы Rails знал, какую таблицу открыть.

6 голосов
/ 20 марта 2009

svn: внешние или git-подмодули - определенно способ пойти в такой ситуации.

Конечно, вы захотите иметь возможность протестировать их в обоих приложениях, поэтому вы должны также поделиться своими модельными тестами или спецификациями. Но помните, что модели часто зависят от плагинов, поэтому вы также захотите открыть общий доступ к своей папке плагинов. И вам, вероятно, нужны одни и те же драгоценные камни и одна и та же версия Rails, поэтому вам лучше всего поделиться со всеми поставщиками. Да, и иногда ваш код в lib изменяет ваши модели, поэтому вы захотите поделиться этим. Да, и обязательно предоставьте доступ к любой пользовательской конфигурации в файлах среды.

И вы захотите настроить сервер непрерывной интеграции для запуска вашего набора тестов в обоих приложениях на случай, если изменения уровня модели в вашем основном приложении нарушат работу вашего другого приложения.

Но я имею в виду, что после того, как все это проработано, svn: externals или git submodules - определенно путь для такой ситуации.

Обновление (несколько лет спустя)

Rails Engines - вероятно, лучшая ставка в настоящее время для надежного разделения кода модели между несколькими приложениями. Они могут быть выделены и включены в Gemfile каждого приложения.

4 голосов
/ 19 марта 2009

Я работаю над проектом с похожей проблемой, и мы использовали svn: externals для совместного использования кода модели между двумя приложениями.

По сути, у вас есть директория моделей в одном проекте SVN и вы используете внешнюю в другом проекте для совместного использования кода. Вы можете редактировать код в любом проекте, и он будет обновляться при запуске svn up в другом проекте.

Что касается Rails и ваших скриптов сборки, каталоги двух моделей полностью разделены.

2 голосов
/ 15 сентября 2011

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

Вот пример, я думаю, вы можете получить его, хотя он написан на китайском языке. http://mvj3.github.com/2011/09/13/multiple_rails_apps_sharing_models_folder/

2 голосов
/ 01 июня 2009

Да, сделайте символическую ссылку на каталог моделей, но затем добавьте переменную окружения в ваш environment.rb для каждого экземпляра. Тогда ваши модели могут знать, какой экземпляр его использует, и включить дополнительные проверки, а какие нет.

в среде. Rb:

APP_INSTANCE = "app1"

в модели. Rb

validates_length_of :name, :within => 3..100, :if => :is_app_one?

def is_app_one?
    APP_INSTANCE == "app1"
end
1 голос
/ 02 февраля 2011

Почему бы не использовать композицию вместо наследования?

У меня похожая проблема: приложение администратора и общедоступное приложение с одной и той же базой данных, и только некоторые конкретные методы для некоторых моделей для одного или другого приложения.

В настоящее время я думаю, что смогу создать общее место со многими модулями, куда я бы поместил свои методы. Затем я бы включал нужные мне модули в каждое приложение (в моделях, контроллерах, помощниках и т. Д.), Когда они мне нужны. Это место может находиться в каталоге lib (обновляется с помощью подмодуля git или внешнего svm) или в геме (обновляется с помощью Bundler или аналогичного инструмента).

Что вы думаете об этом?

1 голос
/ 19 марта 2009

Просто любопытно - почему бы не иметь одно приложение с двумя режимами?

У меня есть одно приложение, которое выглядит как одно из дюжины разных приложений, с разными марками и с разными функциями, в зависимости от того, по какому 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? %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...