Rails 5 with Devise - Devise 用户 has_one 登录

Rails 5 with Devise - Devise User has_one Login

我正在为现有数据库制作网站。该数据库来自游戏,我无法对现有的 table 进行太多更改。

我决定使用 Devise 作为身份验证解决方案。 我将为网站使用 Devise 的用户模型,数据库有一个包含一些重要信息的登录 table。

他们将有一个一对一关联,其中用户 has_one 登录和登录属于用户。

我更改了用户注册表以包含一些登录信息。我为此使用了嵌套形式。当我注册时,它应该创建用户和登录名。

我正在尝试这个创建部分,但它不起作用。我尝试了很多不同的方法,但它从来没有奏效。两个主要问题是:

  1. 它创建用户但不创建登录
  2. 它创建了两者,但登录没有我的信息 放在表格里。他们都是空白

我尝试了很多不同的方法:

None 有效。

我正在使用 Rails 5.0.2 和 Devise 4.2.0。

这些是模型:

class Login < ApplicationRecord
  belongs_to :user
  # accepts_nested_attributes_for :user
end

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable

  has_one :login
  # accepts_nested_attributes_for :login
end

一个重要的问题是我应该把accepts_nested_attributes_for放在哪里?我看到人们在属于的模型中使用它,我也看到人们在 has_one 模型中使用它。

这是我的注册控制器:

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    super
    resource.build_login
  end
  def create
    super
  end
  def sign_up_params
    params.require(resource_name).permit(:email, :password, 
                   :password_confirmation, login_attributes:  
                   [:userid, :birthdate, :sex])
  end
end

这是我的观点:

<%= simple_form_for(resource, as: resource_name, url: 
                    registration_path(resource_name)) do |f| %>
  <%= f.error_notification %>
  <%= f.input :email, required: true, autofocus: true, class: 'form-
              control' %>
  <%= f.input :password, required: true, hint: ("No mínimo #
              {@minimum_password_length} caracteres" if 
               @minimum_password_length) %>
  <%= f.input :password_confirmation, required: true %>
  <%= f.simple_fields_for :login do |ff| %>
    <%= ff.input :userid %>
    <%= ff.input :birthdate %>
    <%= ff.label :sex %>
    <%= ff.input_field :sex, collection: [['Feminino', 'F'], 
               ['Masculino', 'M']], class: 'form-control' %>
  <% end %>
  <%= f.button :submit, 'Cadastrar', class: 'btn btn-primary' %>
<% end %>

我希望所有需要的信息都在那里。

我为这个问题找到的大多数答案是 Rails 4 或 Rails 3,也许它们对我不起作用,因为我使用的是 Rails 5。

编辑 #1: 在 RegistrationController 中添加了创建方法。

编辑 #2: 在用户 accepts_nested_attributes_for 中,字段没有出现,所以我将 accepts_nested_attributes_for 更改为登录模型。

这里是代码现在的日志:

Started POST "/users" for 127.0.0.1 at 2017-07-14 20:24:40 -0300
Processing by Users::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>
      "habj5iep5SaE5nkyimzFyVslsCAIvy7ZokmM
       KA8WDgbgQkYCa/mofo83sllRiwX13OCkPXIjbkR+CcDKBICXOw==",
       "user"=>{"email"=>"breno@gmail.com", "password"=>"[FILTERED]", 
       "password_confirmation"=>"[FILTERED]", "login"=>
      {"userid"=>"breno1", "birthdate"=>"13/07/2017", "sex"=>"M"}}, 
       "commit"=>"Cadastrar"}
Unpermitted parameter: login
(10.8ms)  BEGIN
User Exists (10.1ms)  SELECT  1 AS one FROM `users` WHERE 
  `users`.`email` = BINARY 'breno@gmail.com' LIMIT 1
SQL (11.5ms)  INSERT INTO `users` (`email`, `encrypted_password`, 
  `created_at`, `updated_at`) VALUES ('breno@gmail.com', 
  'ale6ZB5JyrYZGYLXvtlwa.c6BA463BvNYkSINfU0C10LoJADEYJ8q', 
  '2017-07-14 23:24:41', '2017-07-14 23:24:41')
(18.3ms)  COMMIT
(12.6ms)  BEGIN
SQL (11.0ms)  UPDATE `users` SET `sign_in_count` = 1, 
  `current_sign_in_at` = '2017-07-14 23:24:41', `last_sign_in_at` = 
  '2017-07-14 23:24:41', `current_sign_in_ip` = '127.0.0.1', 
  `last_sign_in_ip` = '127.0.0.1' WHERE `users`.`id` = 33
(11.6ms)  COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 436ms (ActiveRecord: 85.8ms)


Started GET "/" for 127.0.0.1 at 2017-07-14 20:24:41 -0300
Processing by HomeController#index as HTML
Rendering home/index.html.erb within layouts/application
Rendered home/index.html.erb within layouts/application (0.7ms)
User Load (13.7ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` 
  = 33 ORDER BY `users`.`id` ASC LIMIT 1
Login Load (11.1ms)  SELECT  `login`.* FROM `login` WHERE 
  `login`.`user_id` = 33 LIMIT 1
Rendered layouts/_side_navbar.html.erb (26.0ms)
Completed 500 Internal Server Error in 619ms (ActiveRecord: 24.8ms)



ActionView::Template::Error (undefined method `userid' for 
  nil:NilClass):
4:       <div class="sidenav-header-inner text-center">
5:         <%= image_tag 'avatar-1.jpg', class: 'img-fluid rounded-
    circle' %>
6:         <h2 class="h5 text-uppercase">
7:           <%= current_user.login.userid %>
8:         </h2>
9:         <span class="text-uppercase">
10:           <%= current_user.is_admin? ? 'administrador' : 'jogador' 
    %>

app/views/layouts/_side_navbar.html.erb:7:in 
`_app_views_layouts__side_navbar_html_erb__415501206315934300_
    70011534596860'
app/views/layouts/application.html.erb:13:in 
`_app_views_layouts_application_html_erb__1458307398416558594_
    70011827322320'
Rendering /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    template_error.html.erb within rescues/layout
Rendering /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    _source.html.erb
Rendered /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    _source.html.erb (32.9ms)
Rendering /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    _trace.html.erb
Rendered /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    _trace.html.erb (5.0ms)
Rendering /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    _request_and_response.html.erb
Rendered /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    _request_and_response.html.erb (1.7ms)
Rendered /home/prikster/.rvm/gems/ruby-2.3.1/gems/actionpack-
    5.0.2/lib/action_dispatch/middleware/templates/rescues/
    template_error.html.erb within rescues/layout (62.6ms)

accepts_nested_attributes_for 模型正确吗?

在日志中有一行指向 Unpermitted parameter: login。我应该怎么做才能纠正这个问题?

我解决了我的问题。

我只需要在登录与用户的关系中添加一个 required: false

我现在的登录模型是这样的:

class Login < ApplicationRecord
  belongs_to :user, required: false
end

我认为问题出在它尝试 create/save 登录时用户还没有 ID。

最后两个模型都创建了,它们之间有关系,它们都有自己的属性和正确的值。