更新同时具有 belongs_to 和 has_many 关联的文档
Updating a document that has both belongs_to and has_many associations
每当我更新文档时,我的 Rails/Mongoid 应用程序都会遇到问题。
我有三个合集:owners
、vessels
和 modifications
。
class Owner
include Mongoid::Document
has_many :vessels
field :name, type: String
field :uprn, type: String
end
class Vessel
include Mongoid::Document
belongs_to :owner
has_many :modifications
field :name, type: String
attr_accessor :uprn
end
class Modification
include Mongoid::Document
belongs_to :vessel
field :change_description, type: String
end
想法是每个所有者拥有多艘船(存在 has_many
、belongs_to
关系)并且对每艘船进行了多次修改(同样,has_many
, belongs_to
关系).
创建所有者、容器和更改工作正常。当我尝试更新所有者时,它起作用了。如果我尝试更新修改,它也有效。但是,当我尝试更新属于所有者的船只并对其进行了一些修改时,我收到此错误:
NoMethodError in OwnersController#update
undefined method `values' for # Mongoid::Criteria:0xb50d49d0
这是引发此错误的代码。除了仅修改存储在文档中的数据外,它还会检查所有者是否已更改(这就是 uprn 字段的来源)并相应地更改 owner_id。
def update
@vessel = Vessel.find(params[:id])
@owner = Owner.find_by(uprn: params[:vessel][:uprn])
if @owner.present?
@vessel.owner_id = @owner.id
if @vessel.update(vessel_params)
redirect_to @vessel
else
render 'edit'
end
else
@vessel.errors[:base] << "There is no owner with the UPRN entered."
render 'edit'
end
end
请注意,这仅在两者之间存在 1-n 关联时才会发生。如果每个容器只有一个修改(因此 has_one
、belongs_to
关联),它就可以正常工作。如果我尝试嵌入同样的处理 - 1-1 嵌入更新正常,1-n 嵌入报告相同的错误。如果只有船只及其修改(与所有者无关),它也可以正常工作。当 vessel 与所有者及其修改相关联时,就会发生这种情况。
我正在使用 Ruby 1.9.3、Rails 4.2.1、Mongo 2.6.1 和 Mongoid 4.0.2。
显然,解决此问题的方法是从 Owner 中删除 has_many :vessels
并从 Vessel 中删除 has_many: modifications
,因此生成的代码如下所示:
class Owner
include Mongoid::Document
field :name, type: String
field :uprn, type: String
end
class Vessel
include Mongoid::Document
belongs_to :owner
field :name, type: String
attr_accessor :uprn
end
class Modification
include Mongoid::Document
belongs_to :vessel
field :change_description, type: String
end
删除这两行后,应用程序运行正常。
好像是字段名的问题,如果任何字段包含单词"change"就会出现错误。希望这对其他人有帮助。
每当我更新文档时,我的 Rails/Mongoid 应用程序都会遇到问题。
我有三个合集:owners
、vessels
和 modifications
。
class Owner
include Mongoid::Document
has_many :vessels
field :name, type: String
field :uprn, type: String
end
class Vessel
include Mongoid::Document
belongs_to :owner
has_many :modifications
field :name, type: String
attr_accessor :uprn
end
class Modification
include Mongoid::Document
belongs_to :vessel
field :change_description, type: String
end
想法是每个所有者拥有多艘船(存在 has_many
、belongs_to
关系)并且对每艘船进行了多次修改(同样,has_many
, belongs_to
关系).
创建所有者、容器和更改工作正常。当我尝试更新所有者时,它起作用了。如果我尝试更新修改,它也有效。但是,当我尝试更新属于所有者的船只并对其进行了一些修改时,我收到此错误:
NoMethodError in OwnersController#update
undefined method `values' for # Mongoid::Criteria:0xb50d49d0
这是引发此错误的代码。除了仅修改存储在文档中的数据外,它还会检查所有者是否已更改(这就是 uprn 字段的来源)并相应地更改 owner_id。
def update
@vessel = Vessel.find(params[:id])
@owner = Owner.find_by(uprn: params[:vessel][:uprn])
if @owner.present?
@vessel.owner_id = @owner.id
if @vessel.update(vessel_params)
redirect_to @vessel
else
render 'edit'
end
else
@vessel.errors[:base] << "There is no owner with the UPRN entered."
render 'edit'
end
end
请注意,这仅在两者之间存在 1-n 关联时才会发生。如果每个容器只有一个修改(因此 has_one
、belongs_to
关联),它就可以正常工作。如果我尝试嵌入同样的处理 - 1-1 嵌入更新正常,1-n 嵌入报告相同的错误。如果只有船只及其修改(与所有者无关),它也可以正常工作。当 vessel 与所有者及其修改相关联时,就会发生这种情况。
我正在使用 Ruby 1.9.3、Rails 4.2.1、Mongo 2.6.1 和 Mongoid 4.0.2。
显然,解决此问题的方法是从 Owner 中删除 has_many :vessels
并从 Vessel 中删除 has_many: modifications
,因此生成的代码如下所示:
class Owner
include Mongoid::Document
field :name, type: String
field :uprn, type: String
end
class Vessel
include Mongoid::Document
belongs_to :owner
field :name, type: String
attr_accessor :uprn
end
class Modification
include Mongoid::Document
belongs_to :vessel
field :change_description, type: String
end
删除这两行后,应用程序运行正常。
好像是字段名的问题,如果任何字段包含单词"change"就会出现错误。希望这对其他人有帮助。