Модель моего проекта имеет отношение многие ко многим к Пользователям (участникам). У меня есть форма приглашения, которая позволяет пользователям вводить электронную почту, чтобы добавить участников в проект. Если пользователь вводит неверный адрес электронной почты или адрес электронной почты, который не соответствует пользователю в базе данных, ошибка не отображается. Я хотел бы предоставить сообщение об ошибке. Каков наилучший способ сделать это?
Я создал метод invite
в модели проекта и запускаю его, только если в контроллере приглашений существует @user
. Я хотел бы предоставить сообщение об ошибке, что участник не был добавлен, потому что пользователь не существует.
Форма приглашения
<%= form_with(url: "/projects/#{@project.id}/invitation", method: "post") do %>
<div class="mb-3">
<%= text_field_tag :email, nil, class: "border border-gray rounded w-ful py-2 px-3", placeholder: "Email Address", autofocus: true %>
</div>
<%= submit_tag("Invite", class: 'button') %>
<% end %>
Приглашение Контроллер
module Projects
class InvitationController < ApplicationController
before_action :set_user
# POST /projects/{id}/invitation
# POST /projects/{id}/invitation.json
def create
@project = Project.find(params[:project_id])
if @user
@project.invite(@user)
end
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: "User was successfully added." }
format.json { render :show, status: :created, location: @project }
else
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
private
def set_user
@user = User.with_email(params[:email]).first
end
end
end
Модель проекта
class Project < ApplicationRecord
include ActivityRecorder
belongs_to :user
has_many :tasks
has_many :activities, -> { order(created_at: :desc) }
has_many :subjects, -> { order(created_at: :desc) }, as: 'subject'
has_and_belongs_to_many :members,
class_name: 'User',
join_table: "members_projects",
foreign_key: "projects_id",
association_foreign_key: "users_id"
validates_presence_of :title, :description, :user
def invite(user)
self.members << user unless self.members.include?(user)
end
end
Модель пользователя
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :projects
has_and_belongs_to_many :projects_as_member,
class_name: 'Project',
join_table: "members_projects",
foreign_key: "users_id",
association_foreign_key: "projects_id"
scope :with_email, ->(email) { where("email = ?", email) }
def get_md5_email
Digest::MD5.hexdigest(self.email)
end
end
Контроллер проектов
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
before_action :require_user
before_action :verify_project_access, only: [:show]
# GET /projects
# GET /projects.json
def index
@projects = Project.where(user: current_user).or(Project.where(id: current_user)).order('updated_at DESC')
end
# GET /projects/1
# GET /projects/1.json
def show
@task = Task.new
end
# GET /projects/new
def new
@project = Project.new
end
# GET /projects/1/edit
def edit
end
# POST /projects
# POST /projects.json
def create
@project = Project.new(project_params)
@project.user = current_user
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: "Project was successfully created." }
format.json { render :show, status: :created, location: @project }
else
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if @project.update(project_params)
format.html { redirect_to @project, notice: "Project was successfully updated." }
format.json { render :show, status: :ok, location: @project }
else
format.html { render :edit }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
# DELETE /projects/1
# DELETE /projects/1.json
def destroy
@project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: "Project was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
@project = Project.find(params[:id])
end
# Only allow a list of trusted parameters through.
def project_params
params.require(:project).permit(:title, :description, :notes)
end
def verify_project_access
if @project.user != current_user
flash[:danger] = "You don't have access this project"
redirect_to projects_url
end
end
end