Mongoid: встроенный один в один, с чистым вводом json - PullRequest
0 голосов
/ 04 июля 2011

Я пытаюсь встраивать модель монгоида один в один , где "встроенный дочерний элемент" - это чистый json-вход, поступающий из внешнего API.

Родительский документ определен следующим образом:

. / Приложение / модели / user.rb

class User
  include Mongoid::Document

  field :nickname, :type => String

  embeds_one :watchlist

  def self.create_with_omniauth(auth)
    create! do |user|
      user.nickname = auth['user_info']['nickname']
    end
  end
end

дочерний элемент определяется следующим образом (используя сочетание «mongo ruby ​​driver» и «mongoid ORM»):

. / Приложение / модели / watchlist.rb

require 'mongo'
class Watchlist
  include Mongoid::Document

  embedded_in :user

  def self.watched(nickname)  
    conn = FaradayStack.build 'https://api.github.com'
    #resp = conn.get '/users/:nickname/watched'
    resp = conn.get '/users/lgs/watched'

    db   = Mongo::Connection.new.db('gitwatch_dev')
    coll = db.collection('watchlist')
    coll.insert(resp.body)
  end
end

Контроллеры выглядят так:

приложение / контроллеры / home_controller.rb

class HomeController < ApplicationController
  def index
    if current_user
      nickname = request.env["omniauth.auth"]
      @watched = Watchlist.watched(nickname)
    end
  end
end

приложение / контроллеры / sessions_controller.rb

class SessionsController < ApplicationController
  def create
    auth = request.env["omniauth.auth"]
    #user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
    user = User.where(:provider => auth['provider'], :uid => auth['uid']).first || User.create_with_omniauth(auth)
    session[:user_id] = user.id
    redirect_to root_url, :notice => "Signed in!"
  end
...
end

Теперь, что я получаю, это gitwatch_dev mongodb с двумя несвязанными «моделями монго», в монго кли они выглядят так:

> db.users.find()
{ "_id" : ObjectId("4e117b951d41c80b14000001"), "provider" : "github", "uid" : "1573", "name" : "Luca G. Soave", "email" : "luca.soave@gmail.com", "nickname" : "lgs", "token" : "a512434559b07feb0a98d199238764sde9876", "secret" : null, "user_hash" : "{\"plan\"=>{\"name\"=>\"free\", \"collaborators\"=>0, \"space\"=>307200, \"private_repos\"=>0}, \"gravatar_id\"=>\"9c7d80ebc20ab8xx994e57519ae\", \"company\"=>\"http://www.linkedin.com/in/lucasoave\", \"name\"=>\"Luca G. Soave\", \"created_at\"=>\"2008/02/28 05:26:40 -0800\", \"location\"=>\"Milan - Italy\", \"disk_usage\"=>113860, \"collaborators\"=>0, \"public_repo_count\"=>32, \"public_gist_count\"=>85, \"blog\"=>nil, \"following_count\"=>140, \"id\"=>1573, \"owned_private_repo_count\"=>0, \"private_gist_count\"=>2, \"type\"=>\"User\", \"permission\"=>nil, \"total_private_repo_count\"=>0, \"followers_count\"=>9, \"login\"=>\"lgs\", \"email\"=>\"luca.soave@gmail.com\"}" }

> db.watchlist.find()
{ "_id" : ObjectId("4e117bd31d41c80b14000002"), "open_issues" : 47, "url" : "https://api.github.com/repos/mojombo/grit", "watchers" : 997, "homepage" : "http://grit.rubyforge.org/", "master_branch" : null, "language" : "Ruby", "fork" : false, "pushed_at" : "Sat Jul 02 2011 01:02:45 GMT+0200 (CEST)", "created_at" : "Mon Oct 29 2007 15:37:16 GMT+0100 (CET)", "git_url" : "git://github.com/mojombo/grit.git", "html_url" : "https://github.com/mojombo/grit", "private" : false, "size" : 2482, "owner" : { "url" : "https://api.github.com/users/mojombo", "login" : "mojombo", "avatar_url" : "https://secure.gravatar.com/avatar/25c7c18223fb42a4c6ae1c8db6f50f9b?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png", "id" : 1 }, "description" : "Grit gives you object oriented read/write access to Git repositories via Ruby.", "name" : "grit", "svn_url" : "https://svn.github.com/mojombo/grit", "ssh_url" : "git@github.com:mojombo/grit.git", "clone_url" : "https://github.com/mojombo/grit.git", "forks" : 140 }
...
...

в то время как я хотел бы получить вложенный json «child in parend», что-то вроде встраиваемой модели «один в один» с монгоидом пример:

{
  "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
  "name" : {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
    "vorname" : "Heinrich",
    "nachname" : "Heine"
  }
}

Чем, я также ищу это в "чистом монгоиде" без беспорядка драйверов рубина, но не могу найти способ ...

ОБНОВЛЕНИЕ 6 июля 2011 - благодаря Рубишу Гупте:

наконец-то работает с

user.create_watchlist['dynamic_attribute'] = resp.body

в родительской модели пользователя: app / models / user.rb, см. Полный код на http://www.pastie.org/2169671

1 Ответ

1 голос
/ 04 июля 2011

Проблема здесь с этими строками:

db   = Mongo::Connection.new.db('gitwatch_dev')
coll = db.collection('watchlist')
coll.insert(resp.body)

Здесь вы получаете доступ к списку коллекций, который вы не хотите создавать и хотите встроить записи в коллекцию пользователей.

Правильным способом было бы сделать функцию watch(repo), подобную следующей в User:

def watch(repo)
  # obtain the resp
  self.create_watchlist(resp.body)
end

Но для этого вы должны включить динамические атрибуты в mongoid.yml.

В вашем контроллере вы должны сделать current_user.watch(repo) вместо трех строк, отмеченных выше.

...