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我将删除第二个选项,以避免其他人混淆