如何在使用Devise注册时创建新用户时添加或更新关联的属性?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在使用Devise注册时创建新用户时添加或更新关联的属性?相关的知识,希望对你有一定的参考价值。
我有三种型号:
- 用户可以拥有多个兴趣点和多个位置。
- 用户可以共享相同的兴趣,但兴趣表不应包含重复项,用户也不应该有重复的兴趣。
- 一个地方可以拥有多个用户,并且可以通过其用户拥有兴趣。
我希望能够在注册时创建用户并将其兴趣和地点添加为关联属性。
用户可以共享相同的兴趣,因此如果注册时已经存在兴趣,我想简单地为新用户添加链接。
到目前为止我可以获得的是在与用户注册时添加兴趣,但如果已经存在兴趣,那么我会收到错误并且用户根本没有注册。这是因为我对利益进行了索引,并对利益进行了独特性验证。没有它,它会在兴趣表中添加重复的兴趣。
这是我使用的类:
models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :confirmable, :trackable, :validatable
has_and_belongs_to_many :interests
has_and_belongs_to_many :places
validates :username, uniqueness: { case_sensitive: false }
validates_associated :interests
accepts_nested_attributes_for :interests
def interests_list=value
value.split(',').each do |interest|
self.interests.build(:name => interest).save
end
end
def interests_list
self.interests.join(',')
end
end
models/place.rb
class Place < ApplicationRecord
has_and_belongs_to_many :users
has_many :interests, through: :users
end
models/interest.rb
class Interest < ApplicationRecord
has_and_belongs_to_many :users
validates :name, uniqueness: { case_sensitive: false }
end
设计形式:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<h3>Add interests</h3>
<div class="field">
<%= f.label :interests %><br />
<%= f.text_field :interests_list %>
</div>
<% if !user_signed_in? %>
<h3>Sign up</h3>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<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>
<% end %>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
我正在使用Rails 5.1.4和Devise 4.4.0
答案
基于Shiko答案,我尝试了一些东西,最后得到了以下结果:
def interests_list=value
current_interest = value.split(',').collect{|interest| interest.strip.downcase}.uniq
current_interest.each do |interest|
self.interests << Interest.find_or_create_by(name: interest)
end
end
有了这个,我能够将几个相同的兴趣归因于几个人而没有在Interest表中重复。谢谢你的帮助!
另一答案
您可以在保存之前快速检查兴趣,或者如果不存在则使用.first_or_create
来创建兴趣,如下所示:
def interests_list=value
current_interest = value.split(',')
unique_interest = current_interest - Interest.where(name: current_interest).pluck(:name)
unique_interest.each do |interest|
self.interests.build(:name => interest).save
end
end
以上是关于如何在使用Devise注册时创建新用户时添加或更新关联的属性?的主要内容,如果未能解决你的问题,请参考以下文章
当角色名称需要与role_id匹配时(使用devise)添加要选择的角色来设计注册表单
Rails - 如何覆盖设计SessionsController以在用户登录时执行特定任务?
每次使用 Rails 3 中的 Devise 登录时,如何检查用户帐户?