Rails избегают дублирования записей в таблице соединений от has_many к has_many - PullRequest
0 голосов
/ 06 сентября 2018

У нас есть обычная модель пользователя (user.rb):

Модель:

class User < ApplicationRecord
  has_many :clientes,         through: :clientes_users
end

И простая модель для клиентов (cliente.rb):

Модель:

class Cliente < ApplicationRecord
    has_many :clientes_users
    has_many :users,            through: :clientes_users
end

Мы создали таблицу соединений (многие ко многим) (clientes_user.rb):

class ClientesUser < ApplicationRecord
    belongs_to :cliente
    belongs_to :user
end

Когда мы создаем пользователя, мы используем:

@user = User.new(
            :email => params[:email],
            :access_level => params[:access_level],
            :password => params[:password_first],
            :password_confirmation => params[:password_confirmation]
        )
        params[:cliente_id].each do |cliente|
            @user.clientes_users.build(
              :cliente => Cliente.find(cliente)
            )
        end
        @user.save

Все отлично работает и наша таблица хранит данные:

enter image description here

Но когда мы обновляем отношения, записи дублируют записи.

enter image description here

Каков наилучший способ избежать такого поведения, если отношения не существуют, вставьте данные, но если они существуют, просто игнорируйте

С уважением.

1 Ответ

0 голосов
/ 07 сентября 2018

Определение ассоциации has_many также дает вам сеттеры и геттеры. @user должен иметь методы cliente_ids и clientes_ids=, которые можно использовать для назначения. Вы можете сделать следующее:

@user = User.create!(
  email: params[:email],
  access_level: params[:access_level],
  password: params[:password_first],
  password_confirmation: params[:password_confirmation],
  cliente_ids: params[:cliente_id]
)

Также обратите внимание, что несоответствия между password и password_first, а также между cliente_ids и cliente_id вводят в заблуждение, было бы неплохо иметь одно и то же имя в обоих случаях.

Когда имена параметров совпадают с атрибутами модели, вы можете пойти еще дальше и сделать это:

@user = User.create!(user_params)

def user_params
  params.require(:user).permit(:email, :access_level, :password, :password_confirmation, :cliente_ids)
end

Удалите require(:user), если параметры контроллера не находятся под ключом user, хотя они, вероятно, должны.

Надеюсь, это помогло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...