Rails 5 с Devise - Devise User has_one Войти
Я делаю сайт для существующей базы данных. Эта база данных из игры, и я не могу внести много изменений в существующие таблицы.
Я решил использовать Devise в качестве решения для аутентификации. Я буду использовать модель User из Devise для веб-сайта, а в базе данных есть таблица Login с некоторыми важными сведениями.
У них будет однозначное объединение, в котором у пользователя есть логин, а логин принадлежит пользователю.
Я изменил форму регистрации пользователя, чтобы получить некоторую информацию для входа. Я использовал для этого вложенную форму. Когда я регистрируюсь, это должно создать пользователя и логин.
Я пытаюсь создать эту часть, но она не работает. Я пробовал много разных способов, но это никогда не работает. Две основные проблемы:
- он создает пользователя, но не создает логин
- он создает оба, но Логин не имеет информации, которую я ввел в форму. Они все пустые
Я пробовал много разных способов:
- переопределить новый метод в RegistrationController, используя resource.build_login
- переопределить метод sign_up_params разрешением внутри
- поместите resource.build_login в новом представлении
- переопределить build_resource и поместить туда resource.build_login
Ни один из них не работает.
Я использую 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.
Edit # 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',
'$2a$11$4le6ZB5JyrYZGYLXvtlwa.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
, Что я должен сделать, чтобы исправить это?
1 ответ
Я решил свою проблему.
Я просто должен был добавить required: false
к логину с пользователем.
Моя модель логина теперь такая:
class Login < ApplicationRecord
belongs_to :user, required: false
end
Я думаю, что проблема заключалась в том, что при попытке создать / сохранить логин у пользователя еще не было идентификатора.
В конце концов, обе модели создаются с отношениями между ними, и у них обоих есть свои атрибуты с их правильными значениями.