我正在开发Ruby on Rails 3应用程序,这是我第一次使用MongoDB.
我一直在思考这个问题几天,我找不到一个好的解决方案.我想讨论两个问题.
该申请是一名学校课程经理.它管理着许多学校,其中包含许多学生,课程,教授和任务.
一所学校的结构 - 有很多 - 是:
学校
主任是学校的管理员.他是唯一一个可以创建教授,学生和课程的人.
关于如何使用Mongoid在MongoDB上构建这个模型集合,我有几天了,我找到了一个可能的解决方案.然而,我来自一个关系数据库世界,也许这是一个糟糕的解决方案,我滥用'嵌入':)
楷模:
class User
include Mongoid::Document
field :first_name
field :last_name
field :email
embedded_in :school, :inverse_of => :director
embedded_in :school, :inverse_of => :students
embedded_in :school, :inverse_of => :professors
end
class School
include Mongoid::Document
field :name
key :name …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用mongoid(2.0.1),rspec(2.5.0),mongoid-rspec(1.4.2)和制作(0.9.5)为People Controller编写我的第一个规范,如果有必要的话.
(注释:组织模型模拟继承自Person模型)
describe PeopleController do
describe "as logged in user" do
before (:each) do
@user = Fabricate(:user)
sign_in @user
end
describe "GET 'index'" do
def mock_person(stubs={})
@mock_person ||= mock_model(Person, stubs).as_null_object
# @mock_person ||= Fabricate.build(:organization)
end
it "should be successful" do
get :index
response.should be_success
end
it "assigns all people as @people" do
Person.stub(:all) { [mock_person] }
get :index
assigns(:people).should eq(mock_person)
end
end
end
Run Code Online (Sandbox Code Playgroud)
运行此规范时,我收到以下错误消息:
1) PeopleController as logged in user GET 'index' assigns all people as @people …Run Code Online (Sandbox Code Playgroud) 场景是:
帐户如何为其他帐户评分?这导致帐户上有两个列表.我评价的人和评价我的人.(my_ratings和ratings_given)
这归结为:
如何在同一实体中使用多个1-N关系在Mongoid中工作?
在Mongoid的文档中,它说你可以使用has_many和belongs_to链接实体.
我目前在账户上有这个
has_many :ratings, :as => "my_ratings"
has_many :ratings, :as => "ratings_given"
Run Code Online (Sandbox Code Playgroud)
这个评分:
belongs_to :user, :as => 'Rater'
belongs_to :user, :as => 'Ratie'
Run Code Online (Sandbox Code Playgroud)
文档没有涵盖这种情况,所以我认为你必须用:作为参数区分两者.
这甚至是遥控器吗?
我是mongo/mongoid的新手,我正在尝试在我的网站表上设置自引用关系.
# sites model
has_many :child_sites, :class_name => 'Site'
belongs_to :parent, :class_name => 'Site'
#controller
@event = current_site.child_sites.build(params[:site])
Run Code Online (Sandbox Code Playgroud)
current_site是一个返回当前站点对象的函数.
我收到此错误 -
#的未定义方法`entries'
Mongoid :: Paranoia为生成标准的模型添加默认范围
#<Mongoid::Criteria
selector: {:deleted_at=>{"$exists"=>false}},
options: {},
class: Line,
embedded: false>
Run Code Online (Sandbox Code Playgroud)
我可以找到生成的Model.deleted的已删除文档,
#<Mongoid::Criteria
selector: {:deleted_at=>{"$exists"=>true}},
options: {},
class: Line,
embedded: false>
Run Code Online (Sandbox Code Playgroud)
我如何覆盖这个,以便我可以搜索已删除和未删除的文档.
PS Model.unscoped不起作用
使用嵌入对象有什么好处?
在我的实践中,当我不在其父级之外使用嵌入式对象时,这是非常罕见的.我的意思是通常的例子comments是embedded_in post:我需要在更新列表中显示最后的注释,我需要显示current_user等的注释.因此注释不能嵌入或者它将是一个痛苦的屁股.
因此,当我需要使用嵌入对象时,很少有用例.
问题是:为什么我应该使用嵌入式对象,即使在那些罕见的用例中,嵌入有什么好处?
如何更改对象ID?它似乎不仅仅是一个常规属性,所以我不确定我是否能够更新该值?
我正在使用Ruby与Mongoid,但我无法弄清楚如何使用ruby驱动程序,任何帮助将不胜感激!
使用Mongoid,是否可以使用"update_all"将值推送到符合特定条件的所有条目的数组字段?
例:
class Foo
field :username
field :bar, :type => Array
def update_all_bars
array_of_names = ['foo','bar','baz']
Foo.any_in(username: foo).each do |f|
f.push(:bar,'my_new_val')
end
end
end
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法一次更新所有用户(将值'my_new_val'推送到每个匹配条目的"foo"字段)使用"update_all"(或类似的东西)而不是循环通过它们来更新他们一次一个.我已经尝试了所有我能想到的东西,到目前为止还没有运气.
谢谢
我正在Rails中构建一个论坛系统,以便更熟悉Rails和Mongoid.我想添加的一个功能是用户可以用来互相发送消息的私人消息系统论坛.在架构设计方面,我可以想到两个解决方案:
用户和消息是使用"has_many"和"belongs_to"相互链接的单独文档.
用户文档
has_many:messages_sent,:class_name =>'Message',:inverse_of =>:message_sender
has_many:messages_received,:class_name =>'Message',:inverse_of =>:message_recipient
和
消息文档
field:created,type:DateTime,default: - > {Time.now}
field:content,type:String
belongs_to:message_sender,:class_name =>'User',:inverse_of =>:messages_sent
belongs_to:message_recipient,:class_name =>'User',:inverse_of =>:messages_received
为了向用户显示他的收件箱,我会查看已some_user.messages_received排序:created并进行过滤,因此我有一个唯一的发件人ID列表,这些列表是在发送最后一封邮件时排序的some_user.
然后,为了显示特定的对话,我只是获取两个参与者之间的所有消息,并根据时间戳交错它们:
messages_in = some_user.messages_received.where(:message_sender => selected_correspondent)
messages_out = some_user.messages_sent.where(:message_recipient => selected_correspondent).
我不喜欢这个解决方案,因为它涉及使用"where"查询多次点击Messages集合以及发送和接收的大量手动过滤和交错消息.努力.
在对话文档中嵌入消息.我将在下面提供用户,消息和对话的代码.会话通过has_and_belongs_to_many(nn,因为用户也可能有很多对话)链接到两个或多个用户.这也可能允许多用户对话.
我喜欢这个解决方案,因为为了向用户显示他的收件箱,我可以使用在Conversation文档中存储和更新的some_user.conversations顺序:last_message_received,不需要过滤.为了显示特定的对话,我不需要交错发送和接收的消息,因为消息已经以正确的顺序嵌入到对话文档中.
此解决方案的唯一问题是当您要添加消息时,找到由两个(或更多)用户共享的正确对话文档.这里建议一个解决方案:mongodb会话系统,但我不喜欢它,因为查询似乎相对昂贵,并且多用户对话的扩展看起来会变得棘手.相反,我在Conversation文档中有一个字段,该字段:lookup_hash是根据参与对话的每个用户的Object ID计算的SHA1哈希.这样,给定两个或更多用户,找到相应的对话文档(或者如果它还不存在则创建它)是微不足道的.
要向对话添加消息,我只使用Conversation.add_message(类方法,而非实例方法,因为对话可能尚不存在),为其提供发件人,收件人和新邮件对象.
我的问题是:考虑到Mongoid(或者一般只是NoSQL)架构设计最佳实践,我做了什么显然是错误的吗?我有什么办法可以改善我的解决方案吗?我使用哈希来查找对话的想法是个坏主意吗?
user.rb
class User
include Mongoid::Document
field :username, type: String
field :joined, type: DateTime, default: ->{ Time.now } …Run Code Online (Sandbox Code Playgroud) 我有一个多域Rails 4应用程序,其中request.domainhttp请求确定我公开给定访问者的功能.
我的应用中的每个域都应该由自己的MongoDB数据库提供服务.例如domain1.com由db_for_domain_1等提供.
我可以在MongoDB文档中阅读有关运行时持久性的内容
Mongoid.override_database("db_for_#{request.domain}")
Run Code Online (Sandbox Code Playgroud)
使我能够动态切换数据库.
但是当我绕过Mongoid并使用mongo Shell方法db.collection.insert()时,如何保持持久性呢?我仍然会在我的应用程序中执行此操作.
答案可能在关于集合访问的MongoDB文档中,但我不明白.那么如何在此操作之前/期间切换数据库?:
MyModel.collection.insert({field_1: "Value 1", field_2: "Value 2"})
Run Code Online (Sandbox Code Playgroud) mongoid ×10
mongodb ×7
ruby ×4
arrays ×1
devise ×1
mongo-shell ×1
mongoid4 ×1
rspec ×1
rspec2 ×1
unit-testing ×1
update-all ×1