Ruby on rails 如何在使用Desive注册时创建新用户时添加或更新关联属性?
我有三个模型:Ruby on rails 如何在使用Desive注册时创建新用户时添加或更新关联属性?,ruby-on-rails,ruby,devise,many-to-many,has-many-through,Ruby On Rails,Ruby,Devise,Many To Many,Has Many Through,我有三个模型: 用户可以有多个兴趣爱好和多个地点 用户可以共享相同的兴趣,但兴趣表不应共享 包含重复项,并且用户不应具有重复项 也是 一个地方可以有多个用户,并且可以通过它的 用户 我希望能够在注册时创建一个用户,并将其兴趣和位置添加为相关属性 用户可以共享相同的兴趣,因此如果在注册时已经存在兴趣,我只想为新用户添加一个链接 到目前为止,我能得到的是在与用户注册时添加兴趣,但是如果兴趣已经存在,那么我会得到一个错误,并且用户根本没有注册。 这是因为我对利益进行了索引,并对利益进行了唯一性验证
- 用户可以有多个兴趣爱好和多个地点
- 用户可以共享相同的兴趣,但兴趣表不应共享 包含重复项,并且用户不应具有重复项 也是
- 一个地方可以有多个用户,并且可以通过它的 用户
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
class Place < ApplicationRecord
has_and_belongs_to_many :users
has_many :interests, through: :users
end
class Interest < ApplicationRecord
has_and_belongs_to_many :users
validates :name, uniqueness: { case_sensitive: false }
end
models/interest.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
class Place < ApplicationRecord
has_and_belongs_to_many :users
has_many :interests, through: :users
end
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和Desive 4.4.0您可以在保存之前快速检查兴趣,或者使用
。如果兴趣不存在,请首先创建兴趣,如下所示:
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
根据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
def interests\u list=值
current|interest=value.split(',).collect{| interest | interest.strip.downcase}.uniq
当前利息。每个人都有利息|
self.interest谢谢你的回答,我尝试了第一个选项,我可以创建一个用户,即使它已经有兴趣了。然而,他是在没有任何利益的情况下被创造出来的。当他有一些新的兴趣和一些已经存在的兴趣时,新的兴趣是属于他的,而不是旧的兴趣。第二个选项不起作用,因为我有一个错误“除非保存父项,否则无法调用create”。@KillianKemps我将删除第二个选项,以避免其他人混淆