Лучшая практика для изоляции уровня доступа к данным в Ruby / Rails - PullRequest
3 голосов
/ 18 февраля 2011

Итак, у меня есть приложение Ruby on Rails. Пусто на данный момент. И позвольте мне с самого начала сказать, что большая часть моего опыта связана с Java, поэтому я могу думать не так, как разработчики RoR. : -)

Что мне нужно сделать, это создать некоторый уровень доступа к данным, скажем, это будет доступ пользователей, так что пусть это будет UserDAO.rb, который в основном будет тогда использовать ActiveRecord или , напрямую обращаясь к базе данных или , получая доступ или к некоторому хранилищу значений ключа или что-либо еще Я могу думать о.

Технически, поскольку у нас нет интерфейсов в Ruby, я могу сделать так, чтобы UserDAO.rb «имел» реализацию (в основном, я говорю о композиции), которая может быть чем угодно, например, UserDAOActiveRecord.rb или UserDAOMongo. .rb или что-нибудь еще в этом роде. UserDAO.rb будет в основном вызывать методы реализации и все. Должно быть легко переключаться между реализациями.

Хотя это звучит как возможное решение, я с нетерпением жду возможности узнать, каковы лучшие методы решения этой проблемы в мире Ruby. Спасибо!

Ответы [ 3 ]

3 голосов
/ 18 февраля 2011

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

Возможно, вы захотите посмотреть: http://sequel.rubyforge.org/

Вы можете создать класс Person, который содержит методы, которые используют экземпляр Sequel для связи с базой данных.

Этот непроверенный код демонстрирует, почему это может быть не очень хорошей идеей:

class Person
  attr_reader :first_name, :last_name

  DataSource = Sequel.sqlite('my_app.db')[:people]

  def initialize(record)
    @first_name = record.first_name
    @last_name = record.last_name
  end

  # Find a record from the database and use it to initialize a new Person object 
  def self.find_by_id(id)
    self.new(Table.where(:id => id))
  end
end
2 голосов
/ 18 февраля 2011

Помните, что ActiveRecord - это не только способ доступа к базе данных, но и шаблон для интеграции ваших данных в ваше приложение: идея о том, что каждая модель контролирует свои собственные данные и сохраняет / извлекает / запрашивает их по мере необходимости,с экземпляром модели, представляющим строку базы данных.

Естественно, вам не нужно использовать этот шаблон, но он является одним из ядер Rails, поэтому рассматривая ActiveRecord как еще один метод доступа к данным, который необходимо абстрагировать,вы теряете много функциональности.

Обратите также внимание, что ActiveRecord уже абстрагирует тип базы данных с помощью адаптера базы данных, поэтому в MySQL, Oracle и т. д. можно легко добавить реляционную базу данных..

Однако, чтобы ответить на ваш вопрос, на самом деле нет необходимости заключать вашу реализацию доступа к данным в другой класс просто для обеспечения согласованного интерфейса.Как вы говорите, ruby ​​не имеет интерфейсов типа Java, но мир ruby ​​также обычно не пытается гарантировать, что разработчики могут делать только законные вещи.Вы можете создать группу классов доступа к данным, которые предлагают один и тот же набор методов, создать модульные тесты, чтобы убедиться, что эти методы согласованы (и выступать в качестве исполняемой документации этих методов), а затем доверить разработчикам правильные вызовы в зависимости от того, чтореализацию они выбирают.Это большое культурное отличие от мира Java, где все закодировано для интерфейсов, а методы являются окончательными, а объекты неизменяемыми.Требуется некоторое привыкание.

1 голос
/ 18 февраля 2011

Алекс, я настоятельно предлагаю вам приобрести книгу Agile Web Devoplment With Rails (4-е издание).Active Record реализует ... шаблон активной записи, поэтому Class является DAO (методы класса представляют dao), а методы instance представляют объект.

Так, например, вы можете иметь

person = Person.find(3)   //Person is the dao
person.name = 'mick'      //name = is the setter for he instance
person.save               // well.. saves the object

Я программировал на Java в течение 10 лет и только начал с ruby ​​..... и это довольно сильно изменилось.

...