Ruby on rails 4 Mongoid模型赢得';t persist通过嵌入一个关系拥有一个
我在基于mongoid4的rails 4应用程序中嵌入时遇到问题。在过去的两天里,我一直在到处寻找答案。这是代码 这是一个教会管理应用程序,带有一个服务模型,嵌入了一个团队和一个乐队。每个团队/乐队都有几个角色,例如“主持”、“交流”,这些角色指的是一个用户 我的模型:Ruby on rails 4 Mongoid模型赢得';t persist通过嵌入一个关系拥有一个,ruby-on-rails-4,mongoid,Ruby On Rails 4,Mongoid,我在基于mongoid4的rails 4应用程序中嵌入时遇到问题。在过去的两天里,我一直在到处寻找答案。这是代码 这是一个教会管理应用程序,带有一个服务模型,嵌入了一个团队和一个乐队。每个团队/乐队都有几个角色,例如“主持”、“交流”,这些角色指的是一个用户 我的模型: class Service include Mongoid::Document ... embeds_one :team, autobuild: true embeds_one :band, autobuild:
class Service
include Mongoid::Document
...
embeds_one :team, autobuild: true
embeds_one :band, autobuild: true
...
accepts_nested_attributes_for :team, :band
end
class Team
include Mongoid::Document
embedded_in :service
has_one :presidence, :class_name => 'User', autosave: true
has_one :message, :class_name => 'User', autosave: true
...
end
class Band
include Mongoid::Document
has_one :lead, :class_name => 'User', autosave: true
has_one :guitar, :class_name => 'User', autosave: true
...
embedded_in :service
end
class User
include Mongoid::Document
embeds_one :profile
belongs_to :team, :inverse_of => :presidence
belongs_to :team, :inverse_of => :message
belongs_to :band, :inverse_of => :lead
belongs_to :band, :inverse_of => :guitar
def fullname
"#{profile.firstname} #{profile.lastname}"
end
def self.find_by_talent(talent)
self.where("profile.talents.name" => talent)
end
end
服务控制员:
# POST /services
# POST /services.json
def create
@service = Service.new(service_params)
respond_to do |format|
if @service.save
format.html { redirect_to @service, notice: 'Service was successfully created.' }
format.json { render action: 'show', status: :created, location: @service }
else
format.html { render action: 'new' }
format.json { render json: @service.errors, status: :unprocessable_entity }
end
end
end
...
def service_params
params.require(:service).permit(:date, :time, :place, :name, :theme, :team => [:id, :precedence, :message ], :band => [:id, :lead, :guitar ])
end
以及_form.html.erb中的表单:
<%= form_for(@service) do |f| %>
...
<%= f.fields_for @service.team do |tf| %>
<%= tf.collection_select :presidence, User.find_by_talent(:presidence), :_id, :fullname, {:include_blank => "select a person"} %>
<%= tf.collection_select :message, User.find_by_talent(:message), :id, :fullname, {:include_blank => "select a person"} %>
<% end %>
<%= f.fields_for @service.band do |bf| %>
<%= bf.collection_select :lead, User.find_by_talent(:lead), :id, :fullname, {:include_blank => "select a person"} %>
<%= bf.collection_select :guitar, User.find_by_talent(:guitar), :id, :fullname, {:include_blank => "select a person"} %>
<% end %>
...
<% end %>
我猜我做错了什么,但我不知道它是在数据库模型中还是在表单中。。。或者其他任何事情……您将无法这样做。创建嵌入文档时,其
\u id
及其所有数据将直接嵌入父文档中。这与关联不同,在关联中,所属的文档获取指向其关联父文档的外键。因此,在这里,您的用户
文档都有团队id
和乐队id
,但是当数据库试图获取文档时,它找不到它们,因为您无法直接查询嵌入的文档;您首先需要父文档。有关更多信息,请参阅
另一个潜在问题是在用户
模型中有多个属于
定义。这也会导致问题,因为对于其中的每一个,Mongoid都会尝试创建团队id
和乐队id
。您应该分别命名它们并指定类名;也许像:主唱团队
和:消息团队
,:主唱乐队
和:吉他乐队
等名字应该会告诉你这是什么样子
我建议将团队和乐队分开,而不是嵌入文档,因为当用户嵌入时,您将无法有效地引用他们
希望这有帮助。非常感谢。我不得不改变我的整个模型结构。我想这就是我的痛处。
2.0.0-p195 :001 > s = Service.last
=> #<Service _id: 52ea18834d61631e7e020000, date: "2014-02-02", time: "10:00", place: "Where it's at", name: "My great name", theme: "The service's theme">
2.0.0-p195 :002 > s.team
=> #<Team _id: 52ea18834d61631e7e030000, >
2.0.0-p195 :003 > s.team.presidence
=> nil
Started POST "/services" for 127.0.0.1 at 2014-01-30 10:16:51 +0100
Processing by ServicesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Ph6lbdHC2FbiANn/fGSzHWprenj3fWKXM40Hrsc5+AM=", "service"=>{"date"=>"2014-02-02", "name"=>"My great name", "theme"=>"The service's theme", "time"=>"10:00", "place"=>"Where it's at", "team"=>{"presidence"=>"52ea18324d61631e81010000", "message"=>"52ea18324d61631e81010000"}, "band"=>{"lead"=>"52ea18324d61631e81010000", "guitar"=>"52ea18324d61631e81010000"}}, "commit"=>"Create Service"}
MOPED: 127.0.0.1:27017 COMMAND database=admin command={:ismaster=>1} runtime: 0.6610ms
MOPED: 127.0.0.1:27017 UPDATE database=service_boot_camp_development collection=users selector={"band_id"=>BSON::ObjectId('52ea18834d61631e7e010000'), "_id"=>{"$nin"=>[]}} update={"$set"=>{"band_id"=>nil}} flags=[:multi]
COMMAND database=service_boot_camp_development command={:getlasterror=>1, :w=>1} runtime: 0.5800ms
MOPED: 127.0.0.1:27017 INSERT database=service_boot_camp_development collection=services documents=[{"_id"=>BSON::ObjectId('52ea18834d61631e7e020000'), "date"=>"2014-02-02", "time"=>"10:00", "place"=>"Where it's at", "name"=>"My great name", "theme"=>"The service's theme", "team"=>{"_id"=>BSON::ObjectId('52ea18834d61631e7e030000')}, "band"=>{"_id"=>BSON::ObjectId('52ea18834d61631e7e010000')}}] flags=[]
COMMAND database=service_boot_camp_development command={:getlasterror=>1, :w=>1} runtime: 2.7460ms