#ruby #ruby-datamapper
#ruby #ruby-datamapper
Вопрос:
Я создаю приложение, отличное от Rails, и использую DataMapper в качестве ORM.
Для объектов, которые будут сопоставлены таблицам SQL, я объявляю классы, которые включают DataMapper::Resource.
Вопрос в том. Можно ли использовать экземпляры этих классов как простые объекты (передавать в методы, манипулировать значениями и т.д.)? Или они должны использоваться только для сохранения данных (например, в классах репозитория)?
Я новичок в мире Ruby и не знаю соглашений. Если у меня есть объект User, у которого есть методы creates, all и т.д., Хорошая ли идея создать другой класс User, который будет хранить только информацию (будет иметь поля состояния и никаких методов)? Аналог POJO (обычный старый Java-объект) в Java?
Комментарии:
1. Это зависит. Для чего бы вы использовали эти PORO?
2. Например, для хранения там информации, полученной от пользователя. Для сохранения в сеансе. И т.д. (различные виды операций, отличных от операций сохранения базы данных)
Ответ №1:
Я вижу, что создание класса-оболочки для простого списка объектов имеет некоторые преимущества. Как вы упомянули в комментарии, если вы хотите хранить данные по-разному, тогда полезно писать разные классы.
Однако я не думаю, что для обычного использования DataMapper или ActiveRecord принято создавать классы-оболочки для списков простых объектов, особенно если вы не добавляете никаких методов в коллекцию. Основная причина, по которой это не распространено, заключается в том, что результаты запроса в ActiveRecord или DataMapper уже похожи на массив. Кроме того, вы на самом деле не получаете никакой дополнительной функциональности, преобразуя экземпляры вашей модели в хэши. Позвольте мне показать какой-нибудь пример:
# collections are array-like
User.all.map(amp;:name) == User.all.to_a.map(amp;:name)
# converting a record to a hash doesn't add much
user = User.first
user_hash = user.attributes
user.name == user_hash[:name]
При этом есть одно предостережение, и оно связано с цепными методами в ORM:
# this is valid chaining
User.all.where(name: "max")
# this raises a NoMethodError for 'where'
User.all.to_a.where(name: "max")
where
это метод ORM, а не метод массива. Итак, если вы преобразуете результат запроса в массив, вы не сможете получить к нему доступ. По этой причине полезно проводить различие между массивами и коллекциями запросов.
Но какую выгоду вы действительно получаете от создания пустого класса-оболочки?
class RecordsInMemory
def initialize(query_collection)
@list = query_collection.map(amp;:attributes)
end
end
records_in_memory = RecordsInMemory.new(User.all)
records_in_memory.list.map(amp;:name)
# versus ...
records_in_memory = User.all.map(amp;:attributes)
records_in_memory.map(amp;:name)
если вы думаете, что в конечном итоге вы добавите методы в список простых объектов, тогда вам следует преобразовать это в класс. Но в остальном, я думаю, достаточно использовать переменные с четкими именами.