[Rails] Add Tags that are related to has_many to Devise User (addition of function to follow tags)

Introduction

By adding Tags that are related to has_many to User of Devise, we will create a function to follow tags like Qiita.

environment

Overview

Devise does not have a username column by default. And there is a lot of information on the net about how to add a username column. However, to create the ability to follow tags, you need to add Tags, which is a has_many relationship, and there isn't much information about this. Therefore, I summarized the method.

code

You can download the Rails project here. https://github.com/GuiltyWorks/DeviseWithTags

bin/rails g migration add_name_to_users name:string bin/rails g model tag bin/rails g model user_tag_relation Create a migration file, Tag model and UserTagRelation model that add name to User.

db/migrate/20200716151945_add_name_to_users.rb


class AddNameToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :name, :string
  end
end

It's not necessary, but I'll add a username column because it's a big deal.

db/migrate/20200716152422_create_tags.rb


class CreateTags < ActiveRecord::Migration[5.2]
  def change
    create_table :tags do |t|
      t.string :name, null: false, unique: true

      t.timestamps
    end
  end
end

Create a tag table like the one above.

db/migrate/20200716152440_create_user_tag_relations.rb


class CreateUserTagRelations < ActiveRecord::Migration[5.2]
  def change
    create_table :user_tag_relations do |t|
      t.references :user, foreign_key: true
      t.references :tag, foreign_key: true

      t.timestamps
    end
  end
end

Create an intermediate table that associates users with tags.

app/models/user.rb


class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  validates :name, { presence: true }
  validates :email, { presence: true, uniqueness: true }

  has_many :user_tag_relations, dependent: :delete_all
  has_many :tags, through: :user_tag_relations
end

Describe has_many in the User model.

app/models/user_tag_relation.rb


class UserTagRelation < ApplicationRecord
  belongs_to :user
  belongs_to :tag
end

Describe belongs_to in the UserTagRelation model.

app/models/tag.rb


class Tag < ApplicationRecord
  validates :name, { presence: true, uniqueness: true }

  has_many :user_tag_relations, dependent: :delete_all
  has_many :users, through: :user_tag_relations
end

Describe has_many in the Tag model.

app/controllers/application_controller.rb


class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
    devise_parameter_sanitizer.permit(:sign_in, keys: [:name])
    devise_parameter_sanitizer.permit(:account_update, keys: [:name, tag_ids: []])
  end
end

Register name and tag_ids in Devise.

config/initializers/devise.rb


config.scoped_views = true

Set it to true instead of false to change the Devise view.

ERB:app/views/devise/registrations/new.html.erb


<div class="field">
  <%= f.label :name %>
  <%= f.text_field :name %>
</div>

Allows you to set a user name on the new registration screen.

ERB:app/views/devise/registrations/edit.html.erb


<div class="field">
  <%= f.label :name %>
  <%= f.text_field :name %>
</div>

<div class="field">
  <%= f.label :tag_ids, "Tags you want follow" %>
  <%= f.collection_check_boxes :tag_ids, Tag.all, :id, :name do |tag| %>
    <div class="form-check">
      <%= tag.label class: "form-check-label" do %>
        <%= tag.check_box class: "form-check-input" %>
        <%= tag.text %>
      <% end %>
    </div>
  <% end %>
</div>

Allows you to set a username and a tag to follow on the user settings screen.

Execution result

DeviseWithTags.jpg

You can now follow tags in your favorite programming language on the user settings screen.

References

[* Rails *] How to use devise (rails5 version)

Recommended Posts

[Rails] Add Tags that are related to has_many to Devise User (addition of function to follow tags)
[Rails] Add column to devise
[Rails] Add strong parameters to devise
[Rails] Addition of Ruby On Rails comment function
Implementation of user authentication function using devise (2)
Rails Addition of easy and easy login function
Implementation of user authentication function using devise (1)
Implementation of user authentication function using devise (3)
[Rails6] How to connect the posting function generated by Scaffold with the user function generated by devise
Use [Rails] devise Guest user function (for portfolio)
Add a tag function to Rails. Use acts-as-taggable-on
[Note] Summary of rails login function using devise ①
How to make a follow function in Rails
Rails follow function
Implementation of Ruby on Rails login function (devise edition)
Introduce devise in Rails to implement user management functionality
Implement user follow function in Rails (I use Ajax) ①