I'm having trouble with my Rails/Mongoid app whenever I'm updating my documents.
I have three collections: owners
, vessels
and 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
The idea is that each owner owns several vessels (there's a has_many
, belongs_to
relationship going on) and that there are several modifications which were done on each vessel (again, has_many
, belongs_to
relationship).
Creating owners, vessels and changes works just fine. When I try to update an owner, it works. If I try to update a modification, it also works. However, the moment I try to update the vessel that belongs to an owner and has some modifications done on it, I'm getting this error:
NoMethodError in OwnersController#update
undefined method `values' for # Mongoid::Criteria:0xb50d49d0
Here's the code that throws this error. Besides just modifying the data stored in the document, it also checks if the owner's changed (that's where the uprn field comes in) and alters the owner_id accordingly.
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
Note that this only happens when there's a 1-n association between the two. If there's just one modification per vessel (so a has_one
, belongs_to
association) it works just fine. Same deal if I try to embed - 1-1 embeds update fine, 1-n embeds report the same error. It also works fine if there's just the vessel and its modifications (no association with the owner). The moment vessel is associated with both the owner and its modifications, this thing happens.
I'm using Ruby 1.9.3, Rails 4.2.1, Mongo 2.6.1 and Mongoid 4.0.2.
Apparently the way to fix this is to remove the
has_many :vessels
from Owner andhas_many: modifications
from Vessel, so that the resulting code looks like:After removing these two lines, the app works just fine.