Implement application / approval mechanism
"A user (Konishi) wants to join a certain community, This is an implementation example in the case of "subscription requires the approval of the community administrator (Onishi)".
Ruby 2.6.5 Rails 5.2.4.2 mysql 5.7
I am creating an application that allows users to belong to various communities. --user model: Holds user information for using the app --Community model: Holds community information --belonging model: Holds community information to which the user belongs. Users can belong to multiple communities.
The following sources are excerpts of related parts only
user.rb
class User < ApplicationRecord
has_many :belongings, dependent: :destroy
has_many :applies, dependent: :destroy
has_many :communities, through: :belongings #The community to which the user belongs
end
community.rb
class Community < ApplicationRecord
has_many :belongings, dependent: :destroy
has_many :applies, dependent: :destroy
has_many :users, through: :belongings #Users who belong to the community
#Returns true if the user belongs to the community
def user_belonging?(user)
users.include?(user)
end
end
belonging.rb
class Belonging < ApplicationRecord
belongs_to :user
belongs_to :community
validates :user_id, presence: true
validates :community_id, presence: true
validates :user_id, uniqueness: { scope: :community_id }
validates :community_id, uniqueness: { scope: :user_id }
end
Apply Apply Add model routing, controller, and view files.
routes.rb
Rails.application.routes.draw do
root 'home#index'
resources :communities do
resources :applies, only: %i[index create destroy]
resources :belongings, only: %i[index create destroy]
end
resources :users, only: [:index, :show]
end
--Application button (placed on the community details screen) (views/communities/show.html.erb)
show.html.erb
<!--If the logged-in user belongs to the community-->
<% if @community.user_belonging?(current_user) %>
<%= link_to 'Withdraw', community_belonging_path(@community, @belonging), method: :delete, data:{ confirm: "community"#{@community.name}Withdraw from the membership. Is it OK?" } ,class:"mini-red-link-btn font-bold text-line-none" %>
<!--If you are not affiliated with the community but are logged in-->
<% elsif current_user %>
<% if @apply %>
<%= link_to 'Cancellation of application', community_apply_path(@community, @apply), method: :delete, class: "mini-red-link-btn font-bold text-line-none" %>
<% else %>
<%= link_to 'Application for membership', community_applies_path(@community), method: :post, class: "mini-green-link-btn font-bold text-line-none" %>
<% end %>
The application button will be displayed under the following conditions.
--After pressing the application button (create action occurs)
applies_controller.rb
class AppliesController < ApplicationController
def create
current_user.applies.create(community_id: apply_params[:community_id])
redirect_to community_url(apply_params[:community_id]), notice: "I applied for membership"
end
private
def apply_params
params.permit(:community_id)
end
end
Do not use Ajax and make sure that the redirect to the same screen occurs. (You may use Ajax)
** The application information is now added to the apply model. ** **
Next, check the waiting list. The administrator (Onishi) opens the "Application waiting list screen" from the relevant community screen.
--Link to application waiting screen (community details screen) (views/communities/show.html.erb)
show.html.erb
<% if user_admin_flg(current_user,@community) == 1 %>
<%= link_to "Approval waiting list", community_applies_path(@community), class:"btn btn-primary" %>
<% end %>
Click the link to open the application waiting list screen.
--Application waiting list screen (views/applies/index.html.erb)
index.html.erb
<div class="container applicant-wrapper">
<h3>List of users waiting for approval</h3>
<div class="row">
<% @applies.each do |app| %>
<div class="col-6">
<% if app.user.image.attached? %>
<%= link_to app.user.image, user_path(app.user), class:"user-icon" %>
<% else %>
<%= link_to user_path(app.user) do %>
<%= image_tag ("no_image.png "), class:"user-icon" %>
<% end %>
<% end %>
 <%= app.user.username %><br>
<%= link_to "Approval", community_belongings_path(app.community, user_id: app.user.id, apply_id: app.id), method: :post, class:"mini-green-link-btn font-bold text-line-none" %>
<%= link_to "Rejected", community_apply_path(app.community, app), method: :delete, class:"mini-red-link-btn font-bold text-line-none" %>
<br>
</div>
<% end %>
</div>
</div>
From the apply model, the application information to the relevant community is displayed in a list. On the same screen, an approval button and a rejection button are also arranged.
When you press the approve button, the following processing will be executed.
--belongings controller
belongings_controller.rb
class BelongingsController < ApplicationController
def create
@belonging = Belonging.create(community_id: belonging_params[:community_id], user_id: belonging_params[:user_id])
Apply.find(belonging_params[:apply_id]).destroy!
redirect_to community_applies_url(@belonging.community), notice:"「#{@belonging.user.username}", But the community:#{@belonging.community.name}I joined."
end
private
def belonging_params
params.permit(:community_id, :user_id, :apply_id)
end
end
If you press the reject button, the following processing will be executed.
--applies controller
applies_controller.rb
class AppliesController < ApplicationController
def destroy
@apply = Apply.find(params[:id])
@apply.destroy!
@comminity = Community.find(params[:community_id])
redirect_to community_url(@comminity), notice: "I canceled my application"
end
end
That's it.
In the text, the apps controller and belongings controller are introduced separately for each action, but I will list them all together at the end.
applies_controller.rb
class AppliesController < ApplicationController
def create
current_user.applies.create(community_id: apply_params[:community_id])
redirect_to community_url(apply_params[:community_id]), notice: "I applied for membership"
end
def destroy
@apply = Apply.find(params[:id])
@apply.destroy!
@comminity = Community.find(params[:community_id])
redirect_to community_url(@comminity), notice: "I canceled my application"
end
def index
@applies = Apply.where(community_id: params[:community_id])
end
private
def apply_params
params.permit(:community_id)
end
end
belongings_controller.rb
class BelongingsController < ApplicationController
def create
@belonging = Belonging.create(community_id: belonging_params[:community_id], user_id: belonging_params[:user_id])
Apply.find(belonging_params[:apply_id]).destroy!
redirect_to community_applies_url(@belonging.community), notice:"「#{@belonging.user.username}", But the community:#{@belonging.community.name}I joined."
end
def destroy
@belonging = Belonging.find(params[:id])
@belonging.destroy!
@comminity = Community.find(params[:community_id])
redirect_to community_url(@comminity), notice: "community"#{@comminity.name}I have withdrawn."
end
private
def belonging_params
params.permit(:community_id, :user_id, :apply_id)
end
end
Since the beginner thought and implemented the logic code with his own head, There may be mistakes and better implementations. I would appreciate it if you could point out.
I think this implementation gives you a better understanding of the many-to-many relationship.
Recommended Posts