Хорошо, допустим, у вас есть модель User
и модель Invite
.Я бы, вероятно, установил отношения следующим образом.
# app/models/user.rb
class User < ApplicationRecord
belongs_to :invite
# ...
end
# app/models/invite.rb
class Invite < ApplicationRecord
has_many :users
# ...
end
Далее я бы создал объект формы для обработки комбинации логики регистрации пользователя и логики кода приглашения:
# app/models/user/registration_form.rb
class User::RegistraionForm
include ActiveModel::Model
attr_accessor :name, :email, :password, :password_confirmation, :invite_code
validate :check_user
validate :check_invite_code
def submit
if valid?
user.invite = invite
return user.save
end
return false
end
private
def check_user
unless user.valid?
user.errors.each do |attribute, message|
errors.add(attribute, message)
end
end
end
def user
@user ||= User.new(name: name, email: email, password: password,
password_confirmation: password_confirmation)
end
def check_invite_code
unless invite.present?
errors.add(:base, 'You must have a valid invite code')
end
end
def invite
@invite ||= Invite.find_by(code: invite_code)
end
end
Это предполагает, что модель Invite
имеет уникальный атрибут code
для каждой записи.
Наконец, вы можете создать контроллер регистрации для пользователя для вновь созданного объекта формы:
# app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
def new
@registration_form = User::RegistraionForm.new
end
def create
@registration_form = User::RegistraionForm.new(registration_params)
if @registration_form.submit
# success! redirect or do something here
else
flash[:alert] = @registration_form.errors.full_message.to_sentence
render :new
end
end
private
def registration_params
params.require(:registration_form).permit(:name, :email, :password,
:password_confirmation, :invite_code)
end
end