两个Rails应用程序共享模型 – Workflow的理想解决scheme是什么?

我目前正在开发一个Rails 3项目,分为四个部分:

  • 面向公众的网站
  • pipe理网站/后台
  • 模型
  • 用于第三方数据访问的API

由于这三个关键组件之间共享模型,所以我想让它们远离一个主要项目,但是每个部分都需要访问这些模型,但我不想重复代码,并且在各处都有不同的版本。

目前我有一个gem中的模型代码,并在每个项目的Gemfile我引用他们用下面的行:

gem "my_models", :path => "../my_models/" 

但是,当我部署到我们的testing服务器上供我的同事评估系统时,我需要从外部存储库中提取模型,因此我将以下行换出:

 gem "my_models", :git => "git@private.repository.com:username/my_models.git" 

这在自己的工作很好,但它的版本相当笨重(即我需要碰撞的版本,每次我想部署到testing服务器的变化),切换线使用git而不是本地,并确保我正确推送文件。

以前我使用的是一个共享的git子模块,但是这同样很尴尬。

我宁愿不把所有东西都build成一个大型项目,因为这些项目往往变得非常怪异,难以维护,如果可能的话,我也想分开关注,所以我对pipe理网站所做的任何改变都没有太多的有机会影响其他组件 – 显然这些模型有潜在的问题,但这是一个我已经考虑和理解的风险。

当涉及到这样的事情时,人们会有什么build议? 或者,我是否完全用错误的方式去做?

一些额外的背景:

这个应用程序是对现有网站的重写,它遵循“将所有内容整合到一个项目中”的模式 – 不幸的是,这里有两个问题:

  1. 这个应用程序的开发很糟糕 – 我inheritance了这个项目,当我第一次拿起它的时候,每个页面的加载时间是一个用户的2分钟 – 这个数字从那以后就减less了,但是仍然存在问题
  2. 我们目前处于我们现有网站的容量限制,我们预计未来6个月我们将需要承担更多的负载 – 但是,通过“一站式”应用扩大规模意味着我们将浪费资源扩大规模该网站的后端不需要它。

从本质上讲,我想分离出两件事 – 前端(即公共网站和API)和后端 – 我所知道的关于软件开发的一切都告诉我,把所有这些结合在一起并不是一个理想的解决scheme(和过去的历史展示我认为将这两者分开是确保前端性能的一个好的举措)。

也许我需要从另一个angular度来看待这个问题 – 在每个项目中保留模型,而不是在项目之间共享它们,而是为每个function区域分配一个function子集(即后端需要知道谁创build了一个职位,但是前端并不关心这一点,所以在模型中读取时忽略该逻辑)。

放下模型项目(把模型放到其他部分之一,我build议你认为更重要的任何东西),把所有的项目放到单一的仓库(单独的项目文件夹),并build立符号链接到模型/ libs / apis /什么

你的代码是高度耦合在一起的,你通常需要一次对less数项目进行修改(比如更新模型更新使用它们的API等)

单回购符号链接设置的一个好处是,你的提交将不再是零散的,通常代表完整的function实现 – 更容易跟踪错误,读取历史和维护代码库

而且当你部署时,你不需要从许多存储库中读取 – 在那里只有一个失败点

发布过程也比较简单,分支机构现在可以保持所有项目的范围

有一些缺陷,如符号链接不能很好地在Windows上工作,但对我来说,它完美的作品

您可以创build一个包含共享模型的可挂载引擎,并从中创build一个gem。 这将优雅地处理名称间距问题。 其他好的方面是你也可以分享你的资产。

观看这个railscast了解更多细节。

您仍然需要通过将需要testing的更改推送到远程回购来pipe理“版本”,但是您可以使用Bundler 1.2的新localconfiguration

http://gembundler.com/man/bundle-config.1.html#LOCAL-GIT-REPOS

这样,它会拿起你的本地提交,你将不必在部署时保持更改您的Gemfile。

我知道这不是您的特定问题的解决scheme。 但我真的build议你把所有的项目合并成一个。 在一个应用程序中拥有所有这些部件是非常平常的,并且没有开销。 我认为这个问题不存在尴尬的解决办法。

你的项目是否有足够的代码覆盖率? 如果是这样的话,我会尝试将逻辑分开,如果在不同的项目中使用模型,只需select一个最适合的模型,然后在其上编写一个API。

然后,您可以使用该API来访问其他项目上的这些模型(最好使用类似ActiveModel的东西)。 你仍然会有一个简单的CRUD,但是所有的核心模型逻辑都是在外部处理的。

不过,一定要好好分解才行。 你想保持你的域名紧密,你创build的每个应用程序,你想拆分的庞然大物。

关于引擎:

我已经使用引擎的同一个问题,它确实有帮助,但我也不得不改变我的Gemfile在开发时指向本地path,推动gem,然后把它拉到当前的项目,这是你的行为不喜欢。

看看Git子树。

这可能适合你

http://igor-alexandrov.github.io/blog/2013/03/28/using-git-subtree-to-share-code-between-rails-applications/

要么

你可以写Rake任务..

例:-

 namespace :sync do desc 'Copy common models and tests from Master' task :copy do source_path = '/home/project/src-path' dest_path = '/home/project/dest-path' # Copy all models & tests %x{cp #{source_path}/app/models/*.rb #{dest_path}/app/models/} %x{cp #{source_path}/spec/models/*_spec.rb #{dest_path}/spec/models/} # Database YML %x{cp #{source_path}/config/database.yml #{dest_path}/config/database.yml} end 

看下面的链接。

http://hiltmon.com/blog/2013/10/14/rails-tricks-sharing-the-model/