2012-03-19 3 views
0

에 의해 쿼리하는 방법을 나는 다음과 같은 모델이 있습니다mongoid - 포함 된 개체

class User 
    include Mongoid::Document 
    store_in :users 

    field :full_name, :type => String 
end 

class Message 
    include Mongoid::Document 

    embeds_one :sender, :class_name => "User" 

    field :text,  :type => String 
end 

나는 그들이 직접 조회 할 수 있도록 분리 된 독립형 컬렉션에 UserMessage를 저장하고 싶은, 내가하고 싶은를 각 메시지 항목에 sender에 대한 사용자 사본 1 부. 내 모델이 이런 종류의 요청에 맞습니까?

사용자 user의 인스턴스가있는 경우 어떻게 메시지를 쿼리 할 수 ​​있습니까? sender = user?

이 나는 ​​시도했다 : 이 Message.where(:sender => user) Message.where('sender.id' => user.id) 모두 작동하지.

Message.where('sender.full_name' => user.full_name) 만 사용했지만 사용할 ID 필드가있을 때 텍스트 필드를 사용하고 싶지 않습니다.

어떻게해야할까요?

나는 메시지/사용자 저장 방법 :

user = User.new 
user.full_name = 'larry' 
user.save 

m = Message.new(:text => 'a text message') 
m.sender = user 
m.save 

을 그리고 데이터베이스 결과 : 당신은 당신이 무엇을 할 수 없어

> db.users.find({ 'full_name' : 'larry'}) 
> db.messages.find({})[0] 
{ 
     "_id" : ObjectId("4f66e5c10364392f7ccd4d74"), 
     "text" : "a text message", 
     "sender" : { 
       "_id" : ObjectId("4f62e0af03642b3fb54f82b0"), 
       "full_name" : "larry" 
     } 
} 
+0

정확합니다. 이것을 대답으로 변환 할 수 있습니다. 그러나 나는 아직도 조금 혼란 스럽다. 나는 항상'Message.where (: sender => user)'가 그것을 할 수있는 방법이라고 생각한다. – larryzhao

답변

1

: 메시지 내부 사용자에게 데이터를 포함 할 경우 http://groups.google.com/group/mongoid/browse_thread/thread/04e06a8582dbeced#

당신은 별도의 모델을 필요로하기 위하여려고하고있다. 이것과 같이 비정규화할 때 나는 일반적으로 네임 스페이스 중 하나이며, 공통 필드가있는 모듈을 모두 에 포함 시켜서 작성합니다. 두 경우 모두 포함 할 수 있습니다. 귀하의 경우에는 발신자라고 부를 수 있습니까?

class Sender 
    include Mongoid::Document 
    include UserProperties 

    class << self 
    def from_user(user) 
     Sender.new(user.attributes) 
    end 
    end 
end 

class User 
    include Mongoid::Document 
    include UserProperties 
end 

module UserProperties 
    extend ActiveSupport::Concern 
    included do 
    field :full_name, type: String 
    end 
end 

class Message 
    include Mongoid::Document 
    embeds_one :sender 
end 

당신은 또한 필요하지 않습니다 : 사용자에 store_in 매크로 - 그것의 이름 는 "사용자"가 될 것입니다 기본적으로합니다.

+0

우수! 그것은 실제로 googlegroup에서 나에게 게시 된 동일한 질문이지만 요즘에는 그것을 확인하기 위해 돌아가는 것을 잊지 않습니다 : P. 슬프게도 다시 모델을 조정해야 할 수도 있습니다. 이미 다른 날에 참조를 사용하기 위해 다시 돌아 왔습니다. – larryzhao

+0

예 Google 그룹에 따라 Durran 응답을 붙여 넣습니다. Google 그룹에 질문을 올리면 이전에했던 질문을 링크 할 수 있습니다. – shingara

+0

옙, 나는 다음에 그것을 할 것이다. – larryzhao

1

.

store_in 메서드를 사용하기 때문에 사용자 문서가 그의 컬렉션에 저장됩니다. 그리고 다른 문서에 저장하려고 시도하십시오 (Message)

정말로 2 개의 모음을 원할 경우 Message 클래스에 has_one :user을 사용해야합니다.

class Message 

    has_one :sender, :class_name => 'User', :foreign_key => 'sender_id' 

end 

당신이 당신의 메시지를 얻을 수 있습니다 후 같은 :

Message.senders은 보낸 사람을 모두 가지고있다. 마찬가지로이 Mongoid 구글 그룹에서 요르단 Durran (Mongoid 리드 개발자)에 의해 설명

+0

감사합니다 shingara, 네, 분리 된 컬렉션에 저장된 사용자 및 메시지를 원하지만 Message 모델에 User라는 복사본을 참조가 아닌 보낸 사람으로 갖고 싶습니다. 그것은 단지'field : sender, : type => User'이어야한다는 것을 의미합니까? – larryzhao

+0

User 클래스에 'embedded_in : message'를 추가해야합니다. – shingara

+0

그러면 사용자가 메시지 컬렉션에 저장되며 직접 쿼리 할 수 ​​없으므로 맞습니까? – larryzhao