嵌入了Devise和Mongoid的自定义字段

时间:2014-06-23 11:16:31

标签: ruby-on-rails devise mongoid field

我正在尝试在设计注册过程中创建自定义字段,该过程嵌入来自其他集合的数据。具体来说,我想将一个国家/地区嵌入用户:

这是我的User.rb模型

class User
  include Mongoid::Document
  include Mongoid::Attributes::Dynamic
  include Mongoid::Paperclip
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

  ## Database authenticatable
  field :email,              type: String, default: ""
  field :encrypted_password, type: String, default: ""

  ## Recoverable
  field :reset_password_token,   type: String
  field :reset_password_sent_at, type: Time

  ## Rememberable
  field :remember_created_at, type: Time

  ## Trackable
  field :sign_in_count,      type: Integer, default: 0
  field :current_sign_in_at, type: Time
  field :last_sign_in_at,    type: Time
  field :current_sign_in_ip, type: String
  field :last_sign_in_ip,    type: String

  field :unconfirmed_email, type: String
  field :confirmation_token, type: String
  field :confirmed_at, type: DateTime
  field :confirmation_sent_at, type: DateTime

  # Data
  field :username, type: String

  embeds_one :country
end

这是我的Country.rb模型

class Country
  include Mongoid::Document
  field :name, type: String

  embedded_in :user

  validates_presence_of :name
end

这是我的应用程序控制器,具有强大的参数:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_in) {|u| u.permit(:signin)}
    devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :username, :password, :password_confirmation, :country => {})}
  end
  def after_sign_in_path_for(resource)
    request.env['omniauth.origin'] || stored_location_for(resource) || profile_path
  end
end

最后是设计/注册/ new.html.erb

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>
  <%= f.text_field :username, autofocus: true, id: "username", placeholder: :name } %>
  <%= f.email_field :email, autofocus: true, id: "email", placeholder: :email } %>
  <%= f.password_field :password, autocomplete: "off", id: "password", placeholder: :password } %>
  <%= f.password_field :password_confirmation, autocomplete: "off", id: "confirm_password", placeholder: :password_confirmation }  %>
  <%= f.collection_select(:country, Country.all, :id, :name, {prompt: "Select a Country",:include_blank => "Please select"}, {class: "form-control", id: "country"}) %>           
  <%= f.submit "Sign up", class:"submit action-button" %>
<% end %>

最令人好奇的是国家参数被正确发送,但设计破坏它,看看这个日志文件:

Processing by Users::RegistrationsController Parameters: 
{"utf8"=>"✓", "authenticity_token"=>"nYX6OC3NVDL2h54KN+1moTTXdqz+KlsCCao7Rref3nQ=", 
  "user"=>{
  "username"=>"test",
  "email"=>"test@test.net",
  "password"=>"[FILTERED]",
  "password_confirmation"=>"[FILTERED]",
  "country"=>"5395a3db6d696e0d32080000"},
"commit"=>"Sign up"}

MOPED: 127.0.0.1:27017 INSERT database=app_development collection=users documents=[
{"_id"=>BSON::ObjectId('53a806cf6d696e04a2040000'),
"email"=>"test@test.net",
"encrypted_password"=>"$2a$10$WiglimkqPq2k7BYgO.B0wuME7u2juGPQlhpyCDq1sDJXYxjDvpU12",
"sign_in_count"=>0,
"username"=>"test",
"confirmation_token"=>"95dfa85e84a37405a74ce005277c8be79df954645f9515fdb06903c75f3d2772",
"confirmation_sent_at"=>2014-06-23 10:51:59 UTC}] flags=[]

我错过了什么吗?感谢

1 个答案:

答案 0 :(得分:0)

您必须在模型中添加accept attributes属性才能接受嵌入的文档字段

在用户模型中

embeds_one :country
accepts_nested_attributes_for :country

在表单中使用fields_for和country以及在application_controller中将已清理的参数作为

devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :username, :password, :password_confirmation, :country_attributes => {:name})}