Реализация подобных ActiveRecord ассоциаций для API-оболочки - PullRequest
11 голосов
/ 10 октября 2011

Я недавно написал ParseResource , который является оболочкой Ruby API для REST API Parse.com REST.

Вот несколько основных примеров использования:

class Post < ParseResource
  fields :title, :author, :body
end
p = Post.create(:title => "Hello world", :author => "Alan", :body => "ipso lorem")

Проект довольно молодой, и особенность, которую я действительно хочу реализовать, - это ассоциации.Примерно так:

class Author < ParseResource
  has_many :posts
  fields :name, :email
end
class Post < ParseResource
  belongs_to :author
  fields :title, :body
end
a = Author.create(:name => "Alan", :email => "alan@example.com")
p = Post.create(:title => "Associated!", :body => "ipso lorem", :author => a)
p.author.class #=> Author
p.author.name #=> "Alan"
a.posts #=> an array of Post objects

Я хотел бы получить любые советы, указания и подводные камни от любого, кто реализовал нечто подобное, а также от любого, кто разбирается в REST API Parse.

Ответы [ 2 ]

3 голосов
/ 19 октября 2011

Я обнаружил, что с помощью DataMapper (http://datamapper.org) довольно легко заставить его работать практически с любым хранилищем данных. Вы можете написать адаптер, который обращается к вашему хранилищу данных, а затем использовать всю мощь DataMapper напрямую, как если бы ваши данные были в SQL. Вот ссылка, которая немного объясняет написание одного из этих адаптеров. http://www.killswitchcollective.com/articles/55_datamapperabstractadapter_101

0 голосов
/ 15 октября 2011

Похоже, что Parse работает, сохраняя объекты в виде хэша пар ключ-значение.Таким образом, в основном у вас есть идентификатор, а затем хеш, с которым вы можете дать волю своему воображению.

Для таких ассоциаций, как ActiveRecord, вам нужен первичный ключ (например, Author.id) и внешний ключ (например, Post.author_id).Author.id прост - просто сделайте его идентификатором объекта Parse.Затем сохраните идентификатор автора для поста внутри поста с ключом 'author_id'.Так что это сторона данных.

В коде есть несколько уровней реализации, которые необходимо учитывать.Для поиска вы стремитесь создать такие методы:

class Author
  def posts
    @posts ||= Post.find(:all, :id => id)
  end
end

class Post
  def author
    @author ||= Author.find(author_id)
  end
end

Это не слишком сложно и может быть сделано разными способами, например, с помощью метапрограммирования.Сложнее сохранить.То, к чему вы стремитесь, по крайней мере со стороны Автора, выглядит примерно так:

class Author
  def after_save
    super
    posts.each do |p|
      p.author_id = id
      p.save
    end
  end
end

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

a = Author.find(1)
a.name = "Joe"
a.save

Как написано after_save загрузит существующие посты (он проходит через posts, который устанавливает @posts), установите author_id для каждого поста (чего не нужносделано в этом случае), а затем сохранить сообщения, хотя ничего не изменило их.Кроме того, что, если сообщение терпит неудачу во время сохранения?В этом случае необходимы транзакции, так что вы можете откатить все это и предотвратить несогласованное состояние.

В ActiveRecord код вы можете видеть тонну логики вокруг вопроса о том, какобрабатывать детей, когда родитель сохранен.Результатом являются гладкие и прозрачные ассоциации, но вовлекаются все виды других вещей; прокси , ассоциативные классы и т. Д.

Мой совет таков.Решите, действительно ли вам нужны гладкие и прозрачные ассоциации.Если нет, то запрограммируйте несколько методов доступа и удобных методов и оставьте все как есть.В противном случае потратьте время на изучение кода ассоциации ActiveRecord напрямую или рассмотрите DataMapper , который, AFAIK, предоставляет вам интерфейс, подобный ActiveRecord, включая ассоциации, с возможностью изменения хранилищ данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...