2015-01-12 4 views
1

У меня возникла проблема с введением дополнительных значений полей пользователя в базу данных с помощью Devise gem. Что мне не хватает?Rails devise не сохраняет дополнительные поля ввода в базу данных

Я использую

ruby 2.1.5p273 
Rails 4.1.8 

Это моя user.rb модель

class User < ActiveRecord::Base 

    belongs_to :country 

    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable, :confirmable, :authentication_keys => [:login] 

    attr_accessor :login, :name, :last_name, :address, :post_number, :city, :mobile 

    validates :username, presence: true, length: {maximum: 25}, :uniqueness => { :case_sensitive => false } 
    validates :name, presence:true 
    validates :last_name, presence:true 
    validates :address, presence:true 
    validates :post_number, presence:true 
    validates :city, presence:true 
    validates :country, presence:true 
    validates :mobile, presence:true 

    def login=(login) 
    @login = login 
    end 

    def login 
    @login || self.username || self.email 
    end 

    def self.find_for_database_authentication(warden_conditions) 
    conditions = warden_conditions.dup 
    if login = conditions.delete(:login) 
     where(conditions).where(conditions).where(["username = :value OR lower(email) = lower(:value)", { :value => login }]).first 
    else 
     where(conditions).first 
    end 
    end 

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_up) << :username << :email << :password << :password_confirmation << :remember_me << :name << :last_name << :address << :post_number << :city << :country_id << :mobile 
    devise_parameter_sanitizer.for(:sign_in) << :login << :username << :email << :password << :remember_me 
    devise_parameter_sanitizer.for(:account_update) << :username << :email << :password << :password_confirmation << :current_password << :name << :last_name << :address << :post_number << :city << :country_id << :mobile 
    end 

end 

контроллер Application (V2, я пытался лодочные пути)

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_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me, :name, :last_name, :address, :post_number, :city, :country_id, :mobile) } 
    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :username, :email, :password, :remember_me) } 
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password, :name, :last_name, :address, :post_number, :city, :country_id, :mobile) } 
    end 

end 

Registratiions/new.html.erb

<h2>Sign up</h2> 

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> 
    <%= devise_error_messages! %> 

    <div class="field"> 
     <%= f.label :email %><br /> 
     <%= f.email_field :email %> 
    </div> 

    <div class="field"> 
     <%= f.label :username %><br /> 
     <%= f.text_field :username, autofocus: true %> 
    </div> 

    <div class="field"> 
     <%= f.label :password %> 
     <% if @validatable %> 
     <em>(<%= @minimum_password_length %> characters minimum)</em> 
     <% end %><br /> 
     <%= f.password_field :password, autocomplete: "off" %> 
    </div> 

    <div class="field"> 
     <%= f.label :password_confirmation %><br /> 
     <%= f.password_field :password_confirmation, autocomplete: "off" %> 
    </div> 

    <hr> 

    <div> 
     <%= f.label :name %><br /> 
     <%= f.text_field :name %> 
    </div> 

    <div> 
     <%= f.label :last_name %><br /> 
     <%= f.text_field :last_name %> 
    </div> 
    <div> 
     <%= f.label :address %><br /> 
     <%= f.text_field :address %> 
    </div> 
    <div> 
     <%= f.label :post_number %><br /> 
     <%= f.text_field :post_number %> 
    </div> 
    <div> 
     <%= f.label :city %><br /> 
     <%= f.text_field :city %> 
    </div> 
    <div> 
     <%= f.label :country_id %><br /> 
     <%= f.select(:country_id, options_from_collection_for_select(Country.all, :id, :name)) %> 
    </div> 
    <div> 
     <%= f.label :mobile %><br /> 
     <%= f.text_field :mobile %> 
    </div> 

    <br><br> 

    <div class="actions"> 
    <%= f.submit "Sign up" %> 
    </div> 
<% end %> 

<%= render "devise/shared/links" %> 

И это бревно, что происходит, когда я представить, что моей форму

Started POST "/users" for 127.0.0.1 at 2015-01-12 21:29:36 +0100 
Processing by RegistrationsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"YXPl+X5Xpib9yG4ywUY2BAOmiGdNUtkQZtIgxqBXbak=", "user"=>{"email"=>"[email protected]", "username"=>"testUser", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "name"=>"Test", "last_name"=>"Test", "address"=>"Test", "post_number"=>"21332", "city"=>"TestCity", "country_id"=>"81831761", "mobile"=>"333666333666"}, "commit"=>"Sign up"} 
    (0.1ms) begin transaction 
    User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1 
    User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER('testUser') LIMIT 1 
    Country Load (0.0ms) SELECT "countries".* FROM "countries" WHERE "countries"."id" = ? LIMIT 1 [["id", 81831761]] 
    User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = '0ddbdfeadb0c6758be3dda41b068fd319e0fd63cefcb16c5b985f90ab16e6784' ORDER BY "users"."id" ASC LIMIT 1 
Binary data inserted for `string` type on column `confirmation_token` 
Binary data inserted for `string` type on column `encrypted_password` 
    SQL (0.3ms) INSERT INTO "users" ("confirmation_sent_at", "confirmation_token", "country_id", "created_at", "email", "encrypted_password", "updated_at", "username") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["confirmation_sent_at", "2015-01-12 20:29:36.962365"], ["confirmation_token", "0ddbdfeadb0c6758be3dda41b068fd319e0fd63cefcb16c5b985f90ab16e6784"], ["country_id", 81831761], ["created_at", "2015-01-12 20:29:36.742990"], ["email", "[email protected]"], ["encrypted_password", "$2a$10$bL6dOOVGzfJ5eOGA8mU/ces7w1CCjJk8Z8rlj6BvSQyqbLgazqrVW"], ["updated_at", "2015-01-12 20:29:36.742990"], ["username", "testUser"]] 
    Rendered devise/mailer/confirmation_instructions.html.erb (0.8ms) 

У меня есть два: любые вопросы

  1. Что я нужно сделать, поэтому разработчик расширит свой SQL-запрос INSERT, чтобы вставить дополнительные значения полей базы данных?
  2. Какой способ написания контроллера приложения devise_parameter_sanitizer правильный?

Thx за помощью

ответ

2

Я нашел решение! В рельсах 4 Вы должны specifiey user_params в контроллере

Это мой users_controller (добавлено user_params)

class UsersController < ApplicationController 

    def index 
    @users = User.all 
    end 

    def new 
    @user = User.new 
    end 

    private 

    def user_params 
    params.require(:user).permit(:username, :email, :password, :password_confirmation, :remember_me, :name, :last_name, :address, :post_number, :city, :country_id, :mobile) 
    end 


end 

И это моя модель пользователя (удалено attr_accessor)

class User < ActiveRecord::Base 

     belongs_to :country 

     # Include default devise modules. Others available are: 
     # :confirmable, :lockable, :timeoutable and :omniauthable 
     devise :database_authenticatable, :registerable, 
      :recoverable, :rememberable, :trackable, :validatable, :confirmable, :authentication_keys => [:login] 

     validates :username, presence: true, length: {maximum: 25}, :uniqueness => { :case_sensitive => false } 
     validates :name, presence:true, length: {maximum: 30} 
     validates :last_name, presence:true 
     validates :address, presence:true 
     validates :post_number, presence:true 
     validates :city, presence:true 
     validates :country, presence:true 
     validates :mobile, presence:true 

     def login=(login) 
     @login = login 
     end 

     def login 
     @login || self.username || self.email 
     end 

     def self.find_for_database_authentication(warden_conditions) 
     conditions = warden_conditions.dup 
     if login = conditions.delete(:login) 
      where(conditions).where(conditions).where(["username = :value OR lower(email) = lower(:value)", { :value => login }]).first 
     else 
      where(conditions).first 
     end 
     end 

    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_up) do |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me, :name, :last_name, :address, :post_number, :city, :country_id, :mobile) end 
    devise_parameter_sanitizer.for(:sign_in) do |u| u.permit(:login, :username, :email, :password, :remember_me) end 
    devise_parameter_sanitizer.for(:account_update) do |u| u.permit(:username, :email, :password, :password_confirmation, :current_password, :name, :last_name, :address, :post_number, :city, :country_id, :mobile) end 
    end 

end 
Смежные вопросы