Config gem devise with has_one assosiation
Bài đăng này đã không được cập nhật trong 8 năm
Xin chào các bạn, hôm nay chúng ta sẽ tìm hiểu về gem devise với has_one assosiation.
Trong bài viết này chúng ta sẽ tìm hiểu cách làm sao để tạo form cho 1 user với 1 address.
#user.rb
class User < ApplicationRecord
has_one :address
end
class Address < ApplicationRecord
belongs_to :user
end
- Đầu tiên, chúng ta sẽ tìm hiểu về gem devise.
install gem
#gem
gem "devise"
#bundle install
install devise
#terminal
rails generate devise:install
config mailer
#config/environments/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end
generate devise for user:
#terminal
rails generate devise user
sau đó chạy: rake db:migrate
thêm các devise cần thiết cho user như đăng nhập, đăng xuất ...
#user.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
khai báo routes cho những modul mình sử dụng. như ở dưới đây là đăng nhập đăng ký và thay đổi password khi quên.
devise_for :users, controllers: {
sessions: "users/sessions",
registrations: "users/registrations",
passwords: "users/passwords"
}
Như vậy chúng ta đã install thành công gem devise.
ở gem này chúng ta có thêm một số hàm đặc trưng để kiểm tra đăng nhập:
before_action :authenticate_member!
member_signed_in?
current_member
member_session
- tiếp theo chúng ta thêm address cho user bằng hasone assosiate
chúng ta thêm nested attribute cho user
#user.rb
accepts_nested_attributes_for :address, allow_destroy: true
sau đó config lại class Users::RegistrationsController < Devise::RegistrationsController
để hiển thị form và save data.
#Users::RegistrationsController
before_action :configure_sign_up_params, only: :create
before_action :configure_account_update_params, only: :update
def new
build_resource {}
self.resource.address = Address.new
respond_with self.resource
end
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up) {|u| u.permit :email,
:phone_number, :name, :password, :password_confirmation,
address_attributes: [:city, :town, :village, :home_number]}
end
def configure_account_update_params
devise_parameter_sanitizer.permit(:account_update) {|u| u.permit :name,
:password, :password_confirmation}
end
Ở đây chúng ta phải config lại hàm khởi tạo đối tượng user của gem devise.
build_resource {}
sẽ trả về 1 object resource, và mình có thể build address nested bằng cách self.resource.address = Address.new
và trả về đối tượng user đã được thay đổi respond_with self.resource
.
Bên cạnh đó chúng ta cũng cần viết nested cho param bằng cách gọi before_action :configure_sign_up_params, only: :create
khi create và before_action :configure_account_update_params, only: :update
khi update.
Cuối cùng ở view chúng ta sẽ build ra form cho việc thêm 1 user với 1 address.
# app/views/users/registrations/new.html.erb
<h1><%= t "devise.edit_register", resource: resource_name.to_s.humanize %></h1>
<div class="col-md-6 col-md-offset-3">
<%= form_for resource, as: resource_name, url: registration_path(resource_name), html: {method: :put} do |f| %>
<%= render "shared/error_messages", object: resource %><br />
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div><%= t "devise.email_confirm_edit_registration", resource: resource.unconfirmed_email %></div>
<% end %>
<div class="field">
<%= f.label :password %> <i>(<%= t "devise.password_cant_blank" %>)</i>
<%= f.password_field :password, autocomplete: "off", class: "form-control" %>
<% if @minimum_password_length %>
<br />
<% end %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<em>(<%= t "devise.password", number_of_password: @minimum_password_length %>)</em>
<%= f.password_field :password_confirmation, autocomplete: "off", class: "form-control" %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(<%= t "devise.need_current_password" %>)</i>
<%= f.password_field :current_password, autocomplete: "off", class: "form-control" %>
</div>
<br />
<div class="actions">
<%= f.submit t("devise.update"), class: "btn btn-primary" %>
</div>
<% end %>
</div>
Như vậy chúng ta đã hoàn thành config cho gem devise với hasone assosiation. Has_one là một trong những assosiation ít được sử dụng trong khi viết web nên sẽ có 1 chút khó khăn nhất định, nhưng nó cũng không quá khó để tim hiểu.
Chúng các bạn thành công. Cám ơn các bạn đã xem bài viết của mình.
link tham khảo: https://github.com/plataformatec/devise
All rights reserved