我目前正在开发一个Rails 3项目,该项目分为四个部分:
由于模型在三个关键组件之间共享,我想让它们远离一个主项目,但是每个部分都需要访问模型,但我不想重复代码并且到处都有不同的版本
目前我在gem中有模型代码,在每个项目的Gemfile中我使用以下行引用它们:
gem "my_models", :path => "../my_models/"
然而,当我部署到我们的测试服务器以供我的同事评估系统时,我需要从外部存储库中提取模型,所以我将上面的行替换为以下内容:
gem "my_models", :git => "git@private.repository.com:username/my_models.git"
这在它自身运行良好,但它在'版本'方面非常笨重(即我每次希望将更改部署到测试服务器时都需要修改版本),切换线路以使用git代替本地的,并确保我正在推送文件。
以前我使用的是共享的git子模块,但这也很尴尬。
我宁愿不把所有内容都构建成一个大项目,因为这些项目往往变得怪异且难以维护,如果可能的话我也想分开关注点,因此我对管理站点所做的任何更改都没有很有可能影响其他组件 - 显然这些模型有可能导致问题,但这是我考虑和理解的风险。
当涉及到这样的事情时,那里的人们会提出什么建议?或者,我是否完全采用了错误的方式?
一些额外的背景:
这个应用程序是对现有网站的重写,遵循“将所有内容整合到一个项目中”的模式 - 不幸的是,这里有两个问题:
基本上我想分开两件事 - 前端(公共网站和API)和后端 - 我所知道的关于软件开发的一切都告诉我,将所有这些结合在一起并不是一个理想的解决方案(和过去的历史告诉我,在确保前端表现方面,将这两者分开是一个很好的举措。)
也许我需要从另一个角度来看待这个问题 - 在每个项目中保留模型,而不是在项目之间共享它们,每个功能区域都有一个简化的功能子集(即后端需要知道谁创建了一个发布,但前端并不真正关心这一点,因此在阅读模型时省略了这种逻辑。)
答案 0 :(得分:19)
放弃模型项目(将模型放入其他部分之一,我建议您考虑“更重要”),将所有项目放入单个存储库(单独的项目文件夹)并对模型/ libs / apis /进行符号链接任何
您的代码高度耦合在一起,您经常需要同时更改少数项目(例如更新模型和更新使用它们的API等)
单个repo-symlink设置的一个好处是你的提交将更少碎片,通常代表完整的功能实现 - 更容易跟踪错误,读取历史记录和维护代码库同样在部署时,您不需要从许多存储库中读取 - 在那里少了一点失败
发布过程也比这样的模型更简单,因为分支现在将包含所有项目的范围
有一些缺点,例如符号链接在Windows上不能很好地工作,但对我来说它完美无缺
答案 1 :(得分:8)
您可以创建一个包含共享模型的可安装引擎,并从中创建一个gem。这将优雅地处理名称间距问题。这里另一个不错的方面是你也可以分享你的资产。
观看此railscast了解详情。
答案 2 :(得分:3)
您仍然需要通过将需要测试的更改推送到远程仓库来管理“版本”,但您可以使用Bundler 1.2的新local
配置
http://gembundler.com/man/bundle-config.1.html#LOCAL-GIT-REPOS
通过这种方式,它将获取您的本地提交,并且您无需在部署时更改Gemfile。
答案 3 :(得分:0)
我知道这不是解决您特定问题的方法。但我真的建议你将所有项目合并为一个。通常将所有这些部件放在一个应用程序中并且没有开销。我认为这个问题没有尴尬的解决办法。
答案 4 :(得分:0)
您的项目是否有足够的代码覆盖率?如果确实如此,我会尝试将逻辑分开,如果在不同的项目中使用模型,只需选择一个最合适的模型并在其上编写API。
然后,您可以使用该API访问其他项目中的那些模型(最好使用类似ActiveModel的东西)。您仍然可以使用简单的CRUD,但所有核心模型逻辑都将在外部处理。
不过,在分手之前一定要好好考虑一下。你想让你的领域紧紧抓住你想要撕裂的巨兽所创建的每个应用程序。
关于引擎:
我已经使用了Engines来解决同样的问题并且它确实有所帮助,但我还必须将我的Gemfile更改为指向开发时的本地路径,推送gem,然后将其拉到当前项目上,这就是行为你不喜欢。
答案 5 :(得分:-1)
看看Git子树。
这可能对你有用..
OR
你可以写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/