ruby-on-rails – Ruby中的存储库或网关模式
如何在
Ruby中实现Repository或Gateway模式?
我来自一个C#世界,我通常抽象出我的数据访问,但是使用ActiveRecord作为Ruby中的默认数据访问机制,如何实现这一点并不明显. 我通常在C#中做的是使用抽象接口,然后为EFCustomerRepository,NHibernateCustomerRepository和InMemoryCustomerRepository提供具体的实现,并根据情况我注入匹配的具体实现. 那么现在,Ruby的方式是什么?! 据我所知,在动态语言中你不需要像DI(依赖注入)这样的东西. 但是你会定义mixin在类或模块级静态使用吗? 如果我想针对内存存储库进行开发,那么如何编写我的业务逻辑?在生产中我会切换到我的ActiveRecord-Repository? 如果我可能在错误的道路上,因为我习惯于用静态类型语言思考.如何以Ruby的方式处理这项任务?基本上我想让我的持久层抽象,它的实现可以互换. 编辑:我指的是robert c. martins (unclebob) keynote about architecture 谢谢你的帮助… 解决方法
我得到你说的话.我也来自.NET背景.摘要你的业务逻辑&持久性逻辑是一个好主意.我还没有找到适合你的宝石.但是你可以轻松地自己滚动一些东西.最后,存储库模式基本上是一个委托给持久层的类.
这是我做的: require 'active_support/core_ext/module/attribute_accessors' class GenericRepository def initialize(options = {}) @scope = options[:scope] @association_name = options[:association_name] end def self.set_model(model,options = {}) cattr_accessor :model self.model = model end def update(record,attributes) check_record_matches(record) record.update_attributes!(attributes) end def save(record) check_record_matches(record) record.save end def destroy(record) check_record_matches(record) record.destroy end def find_by_id(id) scoped_model.find(id) end def all scoped_model.all end def create(attributes) scoped_model.create!(attributes) end private def check_record_matches(record) raise(ArgumentError,"record model doesn't match the model of the repository") if not record.class == self.model end def scoped_model if @scope @scope.send(@association_name) else self.model end end end 然后你可以有一个Post存储库. class PostRepository < GenericRepository set_model Post # override all because we also want to fetch the comments in 1 go. def all scoped_model.all(:include => :comments) end def count() scoped_model.count end end 只需在您的控制器中在before_filter或初始化或任何地方实例化它.在这种情况下,我将其范围限定为current_user,以便它仅获取这些记录并仅为当前用户自动创建帖子. def initialize @post_repository = PostRepository.new(:scope => @current_user,:association_name => 'posts') end def index @posts = @post_repository.all respond_with @posts,:status => :ok end 我遇到了https://github.com/bkeepers/morphine这是一个很小的DI框架.它可能适合你:)但DI不是ruby中使用频繁的模式.此外,我实例化我的repos,以便将它们范围限定为当前用户或其他东西. 我正在努力找到正确的方法去做你所要求的事情,并且如果我找到的话就做一些关于它的文章.但就目前来说,已经足够在持久性和稳定性之间进行彻底切割.我的控制员.如果这样做得当,以后切换到不同的系统将不会是一个大麻烦.或者添加缓存等. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |