我们目前有一个rails应用程序(基本上是一个CRUD),用作移动应用程序的Web服务。
目前,当用户修改应用中的内容时,更改会在移动应用中生效,因为他们使用的是同一个数据库。
我们有什么方法可以将实时数据(由应用程序提取)与用户可以在CRUD中修改的数据分开?我们可以使用DBMS功能,还是宝石?
我们目前正在使用MySQL,但我们正在积极寻找替代方案(例如Postgresql)。
编辑:我们决定在此期间使用文件系统缓存,为每个人提供非最新版本的内容。然后,当一切都好的时候我们继续失效,这样每个人都可以拥有最新的版本。但我不认为这是一个可靠的解决方案......
Edit2:这个问题的全部目的是我们想要控制移动应用程序读取的内容,某种审核。我们希望能够基本管理变更和不同的状态/版本/快照。
答案 0 :(得分:3)
如果我理解正确,这就是你的问题:
解决问题最简洁的方法是:
创建两个数据库(让我们称之为READ DB和WRITE DB),并在它们之间设置主/从复制。因此,无论您在WRITE DB中进行何种查询,它都会在READ DB中进行复制,您可以控制何时以及如何触发复制。几乎每个数据库都支持这种开箱即用的功能。以下是MySQL的说明。你甚至不必为此转而使用PostgreSQL,因为Mater / Slave复制是标准的并且在任何一个都是健壮的。
对于Rails应用,您现在将在config/database/yml
中配置两个数据库:
production:
# configuration for your WRITE DB
adapter: mysql
database: ...
host: ...
username: ...
password: ...
production_read:
# configuration for your READ DB
adapter: mysql
database: ...
host: ...
username: ...
password: ...
然后你有两个选择:
部署两个相同的实例。代码没有变化,只是部署了两个实例,一个用于RAILS_ENV=production_read
的实例用于READ,另一个用RAILS_ENV=production
用于WRITE。更改您的移动应用程序,以便READs转到第一个实例URL,而WRITE转到另一个实例URL。
(OR)
只运行一个Rails应用实例,只需在production
和production_read
数据库之间切换。由于您拥有适当的Web服务,我将假设您正在使用GET请求来读取数据。所有其他(POST / PUT / DELETE / etc)请求都是写请求。如果你不这样做,那么我首先建议你这样做。鉴于您正在使用GET进行读取,那么您将执行以下操作:
# app/controllers/application_controller.rb
class ApplicationController
before_filter do
# Switch to production_read or production configurations
# based on request method
if request.get?
ActiveRecord::Base.establish_connection "production_read"
else
ActiveRecord::Base.establish_connection "production"
end
end
这将根据请求方法在production_read
和production
配置之间切换。您也可以订购before_filter
,以便在您的身份验证和授权之后仅在之后进行切换,最后它在您的控制器逻辑之前发生。
有时也需要对所有模型类执行相同的establish_connection
。因此,在这种情况下,您只需遍历ActiveRecord::Base
子类并调用相同的establish_connection逻辑。哎呀,你甚至可以在切换连接之前省略一些子类!
ActiveRecord::Base.descendants.each do |model_class|
model_class.establish_connection (request.get? ? "production_read" : "production")
end
# Or let's say you want to switch all models *except* User/Session models to the READ DB
(ActiveRecord::Base.descendants - [User, Session]).each do ...
答案 1 :(得分:0)
如果我的问题是正确的,您要找的是将生产数据库与用户可编辑内容分开,并在同步时运行一些验证/失效方法。
这听起来像是一个消息传递系统可以帮到你。
类似的东西:
+-----------+ +------------+
| | | |
| | | |
| ProdDb | | UserDB |<--------- Content
| | | |
| | | |
+-----------+ +------------+
^ +
| |
| |
| |
| +-----------+ |
| | RabbitMQ | |
+-------+| |<----+
| |
| |
| |
|-----------|
| Q1 |
+-----------+
Q
1(我建议RabbitMQ
prodDB
进行写入。答案 2 :(得分:0)
vestal_versions宝石或paper_trail宝石可以帮到你。关于它们有很棒的Railscasts剧集:
答案 3 :(得分:0)
查看高级问题描述,这让我觉得数据库视图可能就是您所需要的。或许更敏捷的解决方案可能是较低特权的用户。
然后,您可以让非CRUD用户通过单独的Rails模型获取数据,该模型连接到另一个较低特权的数据库连接。 Rails 3 can do this easily.问题的大部分都在您的数据库中。基本上使用“仅选择权限”设置数据库。
底线是你应该能够在数据库级别解决这个问题,并在Rails级别上容纳它。