Implement application function in Rails

I will explain how to implement the post application function and cancel function using Rails.

Implementation flow

As a rough flow, we will implement it according to the following procedure.

  1. Create an intermediate table between posts and applicants
  2. Associate models with each other
  3. Define the routing
  4. Define the application function and cancel function in the controller
  5. Create a view of the application button

Create an intermediate table between posts and applicants

Posts can have multiple applicants, and users can subscribe to multiple posts. As a result, posts and users have a many-to-many relationship and require an intermediate table.

Also, in order to distinguish between the poster and the applicant even within the same user, we will define the applicant as taker. If the model name of the post is Post, then you can create an intermediate table called post_takers.

To create an intermediate table, first type the following command in the terminal to create a model.

$ rails g model PostTaker

Open the completed migration file and write as follows.

2020XXXXXXXXXX_create_post_takers.rb


class CreatePostTakers < ActiveRecord::Migration[6.0]
  def change
    create_table :post_takers do |t|
      t.references :post, foreign_key: true
      t.references :taker, foreign_key: {to_table: :users} 
      t.timestamps
    end
  end
end

The point here is the t.references: taker, foreign_key: {to_table:: users} part. By writing like this, you can refer to the users table while defining the name of the applicant taker as the foreign key of the intermediate table. Reference article: https://qiita.com/publichtml/items/1fba15d8071fab66d043

Associate models with each other

Next, write the association in the model.

user.rb


class User < ApplicationRecord
  has_many :post_takers, foreign_key: "taker_id", dependent: :destroy
end

post.rb


class Post < ApplicationRecord
  has_many :post_takers, dependent: :destroy
  has_many :takers, through: :post_takers, dependent: :destroy
end

post_taker.rb


class PostTaker < ApplicationRecord
  belongs_to :taker, class_name: 'User', foreign_key: 'taker_id'
  validates_uniqueness_of :post_id, scope: :taker_id
end

belongs_to: taker, class_name:'User', foreign_key:'taker_id' in post_taker.rb is By writing in this way, you can associate with the applicant associated with the User model. Reference article: https://qiita.com/gyu_outputs/items/421cc1cd2eb5b39e20ad

Also, validates_uniqueness_of: post_id, scope:: taker_id is We have written such validation to prevent more than one same combination of post and applicant from being registered.

Define routing

Describe the action of applying as take and the action of canceling as cancel in the routing as follows.

routes.rb


Rails.application.routes.draw do
  resources :posts do
    member do
      get 'take'
      get 'cancel'
    end
  end
end

In the above, member is used to include the id of the post in the path. Reference article: https://qiita.com/hirokihello/items/fa82863ab10a3052d2ff

Define application function and cancel function in the controller

Add the following description to the controller.

posts_controller.rb


class PostsController < ApplicationController
  before_action :set_post

  def show
    @user = @post.user
  end

  def take
    #Create an intermediate table record between the post and the logged-in user
    PostTaker.create(post_id: @post.id, taker_id: current_user.id)
    #Show flash message (If you don't want to show the flash message, you don't have to write it)
    flash[:notice] = 'The application is complete.'
    #Redirect to post details page
    redirect_to action: "show"
  end

  def cancel
    #Extract records by the corresponding post and logged-in user from the intermediate table
    post_taker = PostTaker.find_by(post_g_id: @post.id, taker_id: current_user.id)
    post_taker.destroy
    flash[:notice] = 'Cancellation is complete.'
    redirect_to action: "show"
  end

  private

  def set_post
    @post = Post.find(params[:id])
  end
end

Create a view of the application button

Finally, create a view of the application button and you're done! The following code is written in haml.

show.html.haml


-#Show the button only if the poster and the logged-in user do not match
- if @user.id != current_user.id
  -#Cases are classified according to whether or not the logged-in user is included in the applicants for the relevant post.
  - if @post.taker_ids.include?(current_user.id)
    = link_to "Cancel application", cancel_posts_path(@post.id), data: { confirm: "Do you want to cancel the application for this post?" }
  - else
    = link_to "Apply", take_posts_path(@post.id), data: { confirm: "Would you like to apply for this post?" }

Recommended Posts

Implement application function in Rails
Implement follow function in Rails
Implement simple login function in Rails
Implement CSV download function in Rails
Implement post search function in Rails application (where method)
[Rails] Implement search function
Implement markdown in Rails
Create authentication function in Rails application using devise
Implement star rating function using Raty in Rails6
[Rails] Implementation of retweet function in SNS application
[Rails] Implement User search function
Implement LTI authentication in Rails
Implement import process in Rails
[Rails] Implement image posting function
[Rails] Implement credit card registration / deletion function in PAY.JP
Implement user follow function in Rails (I use Ajax) ②
Implement user follow function in Rails (I use Ajax) ①
Add a search function in Rails.
Implement tagging function in form object
Implement PHP implode function in Java
Implement a contact form in Rails
Implement Spring Boot application in Gradle
Implement login function in Rails simply by name and password (1)
Implement login function in Rails simply by name and password (2)
Implement login function simply with name and password in Rails (3)
Implement user registration function and corporate registration function separately in Rails devise
[Rails] Implement community membership application / approval function using many-to-many associations
[Rails] A simple way to implement a self-introduction function in your profile
How to implement search functionality in Rails
[Rails] Function restrictions in devise (login / logout)
I tried to implement Ajax processing of like function in Rails
[Rails 6] Ranking function
Implement Rails pagination
[Rails] Category function
Group_by in Rails
Rails follow function
Implemented follow function in Rails (Ajax communication)
Implement star evaluation function in Rails 6 (Webpacker is installed as standard)
How to implement ranking functionality in Rails
Implement button transitions using link_to in Rails
[Rails] Notification function
Nuxt.js × Create an application in Rails API mode
Implement share button in Rails 6 without using Gem
Posting function implemented by asynchronous communication in Rails
How to implement a like feature in Rails
Implement the Like feature in Ajax with Rails.
Implement iteration in View by rendering collection [Rails]
How to make a follow function in Rails
Simple notification function in Rails (only when followed)
About rails application server
Model association in Rails
Adding columns in Rails
Disable turbolinks in Rails
[Rails] Implemented hashtag function
CSRF measures in Rails
How to implement image posting function using Active Storage in Ruby on Rails
[rails] tag ranking function
Implement Rails account BAN
^, $ in Rails regular expression
Rails search function implementation
Use images in Rails