首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未定义的方法`__metadata‘当我试图使用mongoid更新带有嵌入式文档的用户时,在Rails 4中设计

未定义的方法`__metadata‘当我试图使用mongoid更新带有嵌入式文档的用户时,在Rails 4中设计
EN

Stack Overflow用户
提问于 2015-02-25 19:04:12
回答 2查看 1.7K关注 0票数 1

我是RoR的新手,我试着做一个简单的表单,其中一个用户在一个公司中有两个职位,所以我使用devise来管理用户的身份验证和创建。我只是创建一个类位置嵌入到用户中,并允许管理员从位置列表中选择将每个用户都包含到系统中的位置。现在我可以看到表单,选择位置,但是当我试图保存时,我得到了以下错误:

“54ed0c136c6f6337ff0a0000”的未定义方法`__metadata‘:String

我看到了这个请求,这就是主计长收到的:

代码语言:javascript
复制
Request

Parameters:

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"auxoUaTmvkvRvLUUh3kUP0lzYo9aTotajjYVfy01OE0=",
 "user"=>{"first_name"=>"Fabian",
 "last_name"=>"Jara",
 "email"=>"admin@example.com",
 "age"=>"35",
 "position_primary"=>"54ed0c136c6f6337ff0a0000",
 "position_secundary"=>"54ed0c136c6f6337ff0a0011"},
 "commit"=>"Update"}

这是我的用户模型:

代码语言:javascript
复制
class User
  include Mongoid::Document
  include Mongoid::Timestamps
  include User::AuthDefinitions
  include User::Roles
  include Mongoid::Paperclip

  has_many :identities

  embeds_one :position_primary, class_name: "Position"
  embeds_one :position_secundary, class_name: "Position"

  accepts_nested_attributes_for :position_primary, :position_secundary

  has_mongoid_attached_file :image

  validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]

  field :first_name, type: String
  field :last_name, type: String
  field :roles_mask, type: Integer
  field :age, type: Integer

end

这是我的职位模型:

代码语言:javascript
复制
class Position
    include Mongoid::Document

    field :name, type: String
    field :status, type: Boolean

    embedded_in :users
end

这是编辑用户信息的视图:

代码语言:javascript
复制
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => 'form-vertical' }) do |f| %>
  <%= f.input :first_name, :autofocus => true %>
  <%= f.input :last_name %>
  <%= f.input :email, :required => true %>
  <%= f.input :age %>
  <%= f.file_field :image %> <br>

  <%= f.select :position_primary, Position.all.collect {|p| [ p.name, p.id ] }, :prompt => "Select a position" %>
  <br>

  <%= f.select :position_secundary, Position.all.collect {|p| [ p.name, p.id ] }, :prompt => "Select a position" %>
<br>
  <% if current_user.password_required? %>
    <%= f.input :password, :autocomplete => "off", :hint => "leave it blank if you don't want to change it", :required => false %>
    <%= f.input :password_confirmation, :required => false %>
    <%= f.input :current_password, :hint => "we need your current password to confirm your changes", :required => true %>
  <% end %>
  <%= f.button :submit, 'Update', :class => 'btn-primary' %>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>

这是我的RegistrationController:

代码语言:javascript
复制
class Users::RegistrationsController < Devise::RegistrationsController
  before_filter :resource_params, if: :devise_controller?

  def resource_params
    devise_parameter_sanitizer.for(:sign_up) {|user| user.permit(:first_name, :last_name, :email, :password, :password_confirmation)}
    devise_parameter_sanitizer.for(:account_update) {|user| user.permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password)}
  end

  def update
    authorize! :update, @user, :message => 'Not authorized as an administrator.'
    respond_to do |format|

      if @user.update_attributes(user_params)
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
      else
        format.html { render action: 'edit' }
      end
    end
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def user_params
    params.require(:user).permit(:email, :first_name, :last_name, :image, :age, :position_primary, :position_secundary, :roles => [])
  end

  private :resource_params
end

谢谢,如果你能给出什么可能是错误的想法。

EN

回答 2

Stack Overflow用户

发布于 2015-03-03 08:25:28

希望这能帮点忙。当我试图保存一个像embeds_one文档一样的embeds_many文档时,我过去也有同样的错误。

举例说明。我的Rol模型embeds_one进入用户模型,所以我将数组传递到Rol字段,如下所示:

代码语言:javascript
复制
u2 = User.new(name: 'my_name', email: 'my_email@domain.com', password: 'pass', password_confirmation: 'pass', rol: [Rol.new(nombre: 'admin', description: '...')])
u2.save!

这给了我这个错误:#Array:0x00000104812bf8的未定义方法`__metadata‘

因此,我像这样删除了brackets[]并工作:

代码语言:javascript
复制
u2 = User.new(name: 'my_name', email: 'my_email@domain.com', password: 'pass', password_confirmation: 'pass', rol: Rol.new(nombre: 'admin', description: '...'))
u2.save!

我认为devise不可能通过embeds_one文档的正确结构。

票数 1
EN

Stack Overflow用户

发布于 2018-05-22 08:13:56

我也面临着这个问题,我终于发现了到底发生了什么。问题是我有String Mongoid字段:

代码语言:javascript
复制
class MyModel
  include Mongoid::Document

  field :my_field, type: String
end

并使用相同的键将该String字段替换为嵌入式文档:

代码语言:javascript
复制
class MyModel
  include Mongoid::Document

  embeds_one :my_field, class_name: 'MyNestedModel'
end

对于新对象来说,这很好,但是对于未迁移的对象,该字段的内容仍然是String,而不是MyNestedModel的实例。Mongoid试图加载该对象的__metadata,该对象在存储String的记录中不存在。

我为embedded属性使用了一个不同的名称来解决这个问题,这样就不会在Mongo中的旧字段和新字段之间发生冲突。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28727495

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档