[RUBY] Rails learning day 2

Ruby on Rails5 Quick Learning Practice Guide chapter4

4-2-1 Data type

Each column in the database needs a data type. A data type specifies the values that go into it with certain conditions.

Data type Explanation
:boolean Boolean value
:integer Signed integer
:float Floating point number
:string String (short)
:text String (long)
:date date
:datetime Date and time

Distinguish the data inside by adding the above data type to each column

4-2-2 NOT NULL constraint

If the column has no value, the value is set as NULL and saved as a table, but by using NOT NULL, it is possible to specify that the column always contains some value.

・ How to apply NOT NULL constraint There are two ways to apply the NOT NULL constraint. The first is to put constraints when creating a table. The second method is to add a constraint when you want to add a constraint after creating the table.

  1. How to put constraints when creating a table How to create a table by db: migrate after applying NOT NULL constraint to the migration file for creating the table as it is

db/migrate/XXXXXXXXXX_create_tasks.rb


class CreateTasks < ActionRecord::Migration[5.2]
 def change
  create_table :tasks do |t|
   t.string :name, null: false
   t.text :description
...

Since it is a problem if there is no value in the name part, add null after name. After that, add true if null (blank) is acceptable, and false if you don't like blank (NOT NULL).

  1. How to add constraints when you want to add constraints after creating a table
$ bin/rails g migration ChangeTaskNameNotNull

Since the table has already been created, there is no point in changing the migration file. So create a migration file for changes and write the code for changes there

db/migrate/XXXXXXXXXXXX_change_tasks_name_not_null.rb


class ChangeTaskNameNotNull < ActionRecord::Migration[5.2]
 def change
  change_column_null :tasks, :name, false
 end
end

Change the task using change_column_null (change column to null) in the created migration file for change. change_column_null: task name,: column name,: true or false (true is null, false is not null),

Specify the length of the character string column (change method and up method down method)

To specify the length of the character string, either add the information to the migration file for creating the table or create a migration file for adding information to the table for which the information has been decided, as explained above. Is. This time, let's see how to create a migration file for adding information to a table whose information has been decided.

class ChangeTasksNameLimit30 < ActionRecord::Migration[5.2]
 def up
  change_column :tasks, :name, :string, :limit: 30
 end
 def down
  change_column :tasks, name, :string
 end
end

This time, pay attention to the place where the up method and the down method are written instead of the change method. Originally, the change method is a method created by combining the above up method and down method. The reason why the change method is divided into two this time is in [change_column]. If you use change_column in the change method, you can't undo it if something goes wrong. When returning the version, while looking at the upgraded version (up or change), perform the opposite operation to return the version. But that doesn't work with the change method.

4-2-4 Create a unique index

The unique index is also written in the migration file for creating the table or the migration file for addition and modification as described above.

class AddNameIndexToTasks < ActiveRecord::Migration[5.2]
 def change
  add_index :task, :name, unique: true
 end
end

Adding a unique index eliminates duplication of values (name in this case) (no cover)

4-3-6 Write the original verification code (create the validates yourself)

app/models/task.rb


validate :validate_name_not_including_comma

First, put the name of the validate you created in validate.

app/models/tasks.rb


private

def validate_name_not_including_comma
  errors.add(:name,'Cannot contain commas') if name&.include?(',')
end

Define the contents of validate that you created in the private method (because it is useless if it is tampered with from the outside). if name & .include? (',') If there is a name with a comma, it will be executed normally, but if the name has no comma, the result will be nil and an error will occur. If it is a bocchi operator, nil will appear and only the word nil will appear without an error.

4-5-1 session

By having a session, you can keep the state that you are operating any number of times to any page (login state)

session[user_id] = @user.id

@user.id = session[user_id]

The above is the operation to put information in the session. Below is the operation to retrieve the session value.

4-5-2 Create User model (password-digest)

With password-digest, passwords are encrypted and you don't have to worry about password leakage or unauthorized access. To make password-digest compatible, you can use it by writing the code has_secure_password.

app/models/user.rb


class User < ApplicationRecord
  has_secure_password
end

Write has_secure_password in the model. Then there will be a column called password_confimation under the password column. This is the one that lets you enter it twice to confirm your password. It is judged whether these two passwords match when encrypted with password-digest.

4-5-8 Make it easy to get login information

User.find_by(id:session[user_id])

The code is to find the id you are currently in session with, so if you are logged in, you can identify the logged-in user with this code. If you define this as a method in ApplicationController, User.find_by (id: session [user_id]) will work in any action, and you will get information that you are logged in. So create a new method

app/controllers/application_controller.rb


class ApplicationController < ActionController::Base
  helper_method :current_user

 private

 def current_user
   @current_user||=User.find_by(id:session[user_id]) if session[:user_id]
 end
end

"If @current_user is working, @current_user, if not, if user_id is in session, find the information of the sessioning user and set it as variable @current_user" Is defined as the current_user method. This method should not be manipulated from the outside, so put it in the private method

4-5-9 Implement the logout function

Login status becomes logout status with reset_session

app/controllers/session_controller.rb


 def destroy
   reset_session
   redirect_to root_url, notice: 'logged out'
end

So reset_session is defined in the destry controller.

4-5-11-1 Associate User and Task on the database

The important relationship between User and Task is [one-to-many]. It is a situation where there are multiple Tasks for one User. Specific linking will be described.

  1. First, the user column of the task user information must be in the NOT NULL state.

db/migrate/XXXXXXXXXX_AddUserIdToTasks.rb


class AddUserIdToTasks < ActiveRecord::Migration[5.2]
 def up
   execute 'DELETE FROM tasks;'
   add_reference :tasks, user, null: false, index: true
 end

 def down
   remove_reference :tasks, :user, index: true
 end
end

remove_reference: Use reference when you want to add a constraint in a column. remove_reference: tasks,: user, index: true ← Remove this data add_reference: tasks, user, null: false, index: true ← Added a constraint so that user is null: false. execute'DELETE FROM tasks;' ← There may be data where user was null: false before the constraint, if any, an error will occur. So I used this code to delete all the data in the table.

2.1 Build relationships using has_many: tasks and belongs_to, which represent one-to-many relationships.

app/models/user.rb


 has_many :tasks
end

app/models/task.rb


 belongs_to :user
end

The relationship between databases is done by the model, so fill in the model. user has many tasks tasks belongs to user Because it will be a relationship of Has_many: tasks in the user model tasks model belongs_to: user Add.

4-5-11-3 Registration of Task data of logged-in user

The create action to log in is as follows

app/controller/tasks_controller.rb


 def create
   @task = Task.new(task_params)
・
・
・
・
・
 private

 def task_params
   params.require(:task).permit(:name, :descrition)
 end
end

At this rate, @task will create a new task, but you will not know that it is the task of the logged-in user. So rewrite the above code

app/controller/tasks_controller.rb


 def create
   @task = current_user.task.new(task_params)
・
・
・
・
・
 private

 def task_params
   params.require(:task).permit(:name, :descrition)
 end
end

By adding current_user, it becomes a task that means "currently logged in". In other words, if you add current_user at the beginning, it means "logged in". For example Task.find (params [: id]) → Fetch the task with the specified id current_user.tasks.find (params [: id]) → Fetch the specified task from the tasks of the logged-in person.

Utilize 4-8 scope

You can change orders (created_at :: desc) etc. to simpler names using scope.

scope :recent, -> {order(created_at: :desc)}

With this code, order (created_at :: desc) can be rewritten as recent.

Other things I learned

task.errors.full_messages

error information for task is displayed

task.persisted?

You can check if the task has been registered in the database.

if task.errors.present?
  ul#errors_explanation
   -task.errors.hull_messages.each do |message|
      li= message

Use errors.present? to determine if there are any errors.

if user&.authenticate(session_params[:password])

private
 def session_params
   params.require(:session).permit(:email, :password)
 end

Originally user (session_params [: password]), but when encrypted with password-digest Become user & .authenticate (session_params [: password]).

if current_user.admin?

You can check if you have user management privileges with admin. The current_user is added to that, and it becomes an if statement that says "Does the logged-in person have administrative privileges for that user?"

@task = current_user.task.order(created_at: :desc)

order is an operation to sort the list according to the specified criteria This time, the order of arranging based on created_at (created date and time) has changed.

Recommended Posts

Rails learning day 3
Rails learning day 4
Rails learning day 2
rails learning day 1
Rails learning day 2 part 2
Rails learning day 1 part 3
Rails learning day 3 part 2
Rails learning Day 1 Part 2
Programming learning day 3
Java learning day 5
java learning day 2
java learning day 1
Rails Tutorial Chapter 3 Learning
[Rails] Learning with Rails tutorial
Rails Tutorial Chapter 4 Learning
Rails Tutorial Chapter 1 Learning
Rails Tutorial Chapter 2 Learning
Ruby on rails learning record -2020.10.03
Ruby on rails learning record -2020.10.04
Ruby on rails learning record -2020.10.05
Ruby on rails learning record -2020.10.09
4th day of java learning
Ruby on Rails basic learning ①
Ruby on rails learning record-2020.10.07 ②
Ruby on rails learning record-2020.10.07 ①
Ruby on rails learning record -2020.10.06
[Rails g.error]
Rails Tutorial 6th Edition Learning Summary Chapter 10
Java learning (0)
Ruby learning 4
Rails Tutorial 6th Edition Learning Summary Chapter 7
Rails Review 1
Rails API
Rails migration
Ruby learning 5
Rails Tutorial 6th Edition Learning Summary Chapter 4
[Rails] first_or_initialize
Java Day 2018
Rails Tutorial 6th Edition Learning Summary Chapter 9
Rails Tutorial 6th Edition Learning Summary Chapter 6
About Rails 6
Servlet learning
Ruby learning 3
Rails foundation
Rails Tutorial 6th Edition Learning Summary Chapter 5
Rails memorandum
rails tutorial
rails tutorial
rails tutorial
Learning output ~ 11/3 ~
Rails Tutorial 6th Edition Learning Summary Chapter 2
Rails Tutorial Chapter 0: Preliminary Basic Knowledge Learning 5
Ruby learning 2
Maven learning
[Rails] devise
Ruby learning 6
rails tutorial
Rails Tutorial 6th Edition Learning Summary Chapter 3
rails tutorial
Learning output
Rails Tips