[RUBY] [Rails] Register by attribute of the same model using Devise

Introduction

When registering as a user using Devise in Rails, I think that there are times when I want to divide the attributes by parameters while using the same model, but surprisingly there is no article that says this, so I will write it as an article. It is assumed that there is a registration link for other attributes in addition to the new registration and login links (see here for premium membership registration). We want to divide this into attributes by giving parameters such as Boolean while reusing the view and controller with one User model. I would be grateful if you could point out any mistakes.

environment

console


Windows10
ruby 2.6.6
Rails 6.0.3.1
psql (PostgreSQL) 12.3

Add a column

First, add a column to attribute the existing User model (this time isPremium: boolean). The addition of this column is also quite mysterious for beginners, and at first I was not sure and tried to add it to the existing migraition file, but apparently the migration file used when first rails db: migrate was read. Absent? It seems. So create another migration file and write a method to add columns to it.

console


rails g migration AddCulumnToTable

The part of AddCulmnToTable is an arbitrary class name, but usually it seems that something that is easy to understand later, such as Add + column name To table name to be added, is good.

Edit the migration file

Add the following to the migration file you created earlier.

2020~~_add_column_to_table.rb


  def change
    add_column :users, :isPremium, :boolean #add to
    change_column_null :users, :isPremium, false, false #add to
    change_column_default :users, :isPremium, from: nil, to: false #add to
  end

In the part of "add_column: users,: isPremium,: boolean", a column called isPremium of boolean type is added to the users table. Null is prohibited by "change_column_null: users,: isPremium, false, false". But the existing user doesn't have an isPremium column (null), so set it to false as well. "Change_column_default: users,: isPremium, from: nil, to: false" sets the default value. When add_column is done, the default value is "Null", so it is changed to false.

Reflected in database

console


rails db:migrate

The database should be updated based on the migration file you just created.

Strong Parameters settings

In Devise, you can set email and password by default, but when you add other columns, set something called Strong Parameters (username, isPremium this time, etc.).

application_controller.rb


    before_action :configure_permitted_parameters, if: :devise_controller?

    private
    def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:sign_up, keys:[:username, :isPremium])
    end

Now you can register the username and isPremium columns at the time of new registration.

Settings around the controller

With this, it is possible to manually switch the isPremium of the User model and divide it into attributes (such as providing a check box at the time of registration?), But this time I will try to make it a mechanism to automatically switch by link. So create and route the controller (skip if you're already done).

console


rails g devise:controllers users

config/routes.rb


devise_for :users, 
  controllers: {
     registrations: 'users/registrations'
  }

Create a link

After that, paste the link wherever you like (this time it will be home / index). At that time, I will make it possible to pass parameters and divide the attributes.

erb:home/index.html.erb


      <%= link_to "Login", new_user_session_path %>
      <%= link_to "Member registration", new_user_registration_path(premium: "false") %>
Premium membership registration<%= link_to "Here", new_user_registration_path(premium: "true") %>

Both membership registration and premium membership registration have the same "new_user_registration_path", but we pass a variable called premium to differentiate them.

Receive variables on the controller

In "new_user_registration_path", the new action of RegistrationsController of users created earlier should be called, so I will write it.

users/registrations_controller.rb


# GET /resource/sign_up
  def new
    @premium = params[:premium] #add to
    super
  end

Uncomment the new action (#) and put the premium you just passed into @premium. (Here I wrote @premium = params [: premium] after super and got hooked for an hour.)

Pass to View

Since it is not necessary to display it in View, use f.hidden_field etc. (other forms are omitted).

erb:registrations/new.html.erb


<%= f.hidden_field :isPremium, :value => @premium %>

If you write this in an appropriate place in the form, @premium passed from the link will be registered in the isPremium column of the User model.

end

I made it for the time being, but I don't feel like I'm taking a detour. After that, I was worried because I had little understanding of Rails and called super first with the new action of registrations. Please let me know if there is a smarter way!

Recommended Posts

[Rails] Register by attribute of the same model using Devise
Try using the query attribute of Ruby on Rails
[Enum] Let's improve the readability of data by using rails enum
FactoryBot Register multiple data with the same model
[Note] Summary of rails login function using devise ①
[Rails 6] Change redirect destination at the time of new registration / login by devise
A review of the code used by rails beginners
[Rails] Cancel / change the default password validation of devise
Rails6: Input the initial data of ActionText using seed
[Rails] Sort the post list by date or number of likes using the pull-down box
[Rails] Put the same restrictions on multiple pieces of information
[Rails] Introduction of devise Basics
When using the constructor of Java's Date class, the date advances by 1900.
[Rails] How to delete images uploaded by carrierwave (using devise)
[Rails] When the layout change of devise is not reflected
[Rails] How to display the list of posts by category
[Rails] Japaneseize model attribute names
Extending the four-tier model of the architecture proposed by Eric Evans
[Rails] How to convert the URI of the image sent by http to https when using Twitter API
[Rails] Suppress unnecessary SQL by utilizing the cache control of the association
[Rails] Sign-up function using devise error number of arguments (given 0, expected 1)
Replace preview by uploading by clicking the image in file_field of Rails
Problem that the attribute of User model becomes nil in ActionMailer
[rails] Edit of view page created by devise is not reflected
[Rails 5] How to display the password change screen when using devise
[Rails] Introduction of Rubocop by beginners
[Rails] Check the contents of the object
Explanation of the order of rails routes
Check the migration status of rails
[Rails 6] destroy using the resources method
[Rails] I will explain the implementation procedure of the follow function using form_with.
[Register multiple photos] Register multiple rails images at the same time Primitive power technique
[Ruby On Rails] How to search the contents of params using include?
How to make the schema of the URL generated by Rails URL helper https
Get the value of enum saved in DB by Rails with attribute_before_type_cast
[Rails] Manage multiple models using devise gem
Try using || instead of the ternary operator
[Rails] Temporary retention of data by session
Implementation of user authentication function using devise (2)
Test the integrity of the aggregation using ArchUnit ②
The identity of params [: id] in rails
Try using the Rails API (zip code)
part of the syntax of ruby ​​on rails
The process of understanding Gemfile by non-engineers
[Swift] Termination of the program by assertion
Implementation of user authentication function using devise (1)
[Rails] Change the label name of f.label
Implementation of user authentication function using devise (3)
The process of introducing Vuetify to Rails
The contents of the data saved by CarrierWave.
Test the integrity of the aggregation using ArchUnit ③
[Rails6] How to connect the posting function generated by Scaffold with the user function generated by devise
[Rails 6 + Action Mailbox] Those who extracted the plain text of Gmail received by Action Mailbox
[Rails] Set validation for the search function using Rakuten API (from the implementation of Rakuten API)