Rails+PostgreSQL JSONB(섹션 1)
섹션 1: 마이그레이션 및 때
만약 이 글을 계속 읽는다면, 나는 당신이 Ruby, Ruby의 OOP, RoR,Active Record를 이해한다고 가정합니다.
이 화제에 관한 문장은 많지 않다.기존 약관이라도 자세한 설명은 없다.나는 많은 문장을 읽어야만 잘 표현할 수 있다.
이것은 내가 처음으로 한 화제를 깊이 있게 탐구한 것이다.
Rails>=4.2, PostgreSQL>=9.4 필요
PostgreSQL has JSON and JSONB column type. They are look the same, but there are many differences, especially in functionality. I recommend to use JSONB instead of JSON, as JSONB column type is the upgraded version of JSON.
JSONB 열 유형을 사용하는 이유는 무엇입니까?
The advantage of using jsonb is that you can easily integrate relational and non-relation data, with performance that can be better than most non-relational databases like MongoDB.
source: this article
우리의 여정을 시작합시다!(나는 단지 Rails API를 예로 들었을 뿐이지만, 본문은 일반 Rails에서도 실현할 수 있다)
디렉토리:
1. Migration
2. Create
3. Show
4. Validation
5. Update
6. Final Word
1. 이민
그것은 다른 열 유형과 마찬가지로 간단하다.
# db/migrate/*_create_books.rb
class CreateBooks < ActiveRecord::Migration[5.2]
def change
create_table :books do |t|
t.integer :user_id
t.jsonb :payload, null: false, default: '{}'
end
add_index :books, :payload, using: :gin
end
end
참고:우선, 당신은 사용할 필요가 없습니다
null: false, default: '{}'
. 그러나, 나는 당신이 그것을 사용하는 것을 건의합니다.단지 네가 그것이 맞는지 검사할 필요가 없기 때문이다nil
.# if you allow nil OR dont't state default value to a hash
Book.create(user_id: 1)
Book.last.payload['title']
# => NoMethodError (undefined method `[]' for nil:NilClass)
# if you don't allow nil AND state default value to a hash
Book.create(user_id: 1)
Book.last.payload['title']
# => nil
그 다음으로 GIN 색인도 정의했습니다.나는 두 번째 부분에서 이 점을 소개할 것이다.셋째, 나는 열 이름을
payload
로 명명하지만, 루비, rails,postgresql가 허락하면 마음대로 명명할 수 있습니다.창조
레코드 작성도 간단합니다.
book_payload = {
title: 'Hacking Growth',
publisher: 'Currency',
published_date: '2017-04-07',
authors: [
{
id: 1,
name: 'Sean Ellis'
},
{
id: 2,
name: 'Morgan Brown'
}
]
}
Book.create(user_id: 1, payload: book_payload)
됐다!3. 공연
디스플레이 데이터는 매우 간단하다.JSONB로 정의된 모든 열은 해시로 표시되며 모든 키는 문자열로 반환됩니다.
Book.last.user_id
# => 1
Book.last.payload['title']
# => "Hacking Growth"
Book.last.payload['authors'][0]['name']
# => "Sean Ellis"
또한 기호를 사용하여 JSON 객체에 액세스할 수 있도록 시리얼화된 프로그램을 사용자화하려면 다음과 같이 하십시오.# app/models/book.rb
class Book < ApplicationRecord
belongs_to :user
serialize :payload, JsonbSerializers
end
# app/serializers/jsonb_serializers.rb
class JsonbSerializers
def self.dump(hash)
hash.to_json
end
def self.load(hash)
(hash || {}).with_indifferent_access
end
end
Book.last.payload[:title]
# => "Hacking Growth"
4. 검증
JSOB 열 유형의 문제는 검증을 하지 않으면 무모드가 된다는 것이다.이 열에 모든 모드를 입력할 수 있습니다.다음 코드를 확인하십시오.
book_payload = {
title: 'Getting to Plan B',
pubs: 'Harvard Business Review Press',
authors: 'John W Mullins'
rating: 3.5
}
Book.create(user_id: 1, payload: book_payload)
위의 레코드는 DB 형식으로 제출됩니다.대다수 상황에서 이것은 큰 문제다.API 사용자가 제공한 매개 변수가 정확한지 오류인지 어떻게 검증합니까?우리는 반드시 두 가지 절차를 해야 한다.
Rails에서 JSON 모드를 어떻게 사용합니까?우리는 보석을 사용하고 있다.보석은 적지만 내가 유일하게 사용한 것은activerecord_json_validator gems이다.(이gem은 JSON 모드의 초안-04만 제공됨)
Book
모델에 대한 JSON 모드를 생성합니다.우리는 패턴을 우리가 원하는 곳에 놓을 수 있지만, 나는 그것들을 app/models/schemas
에 놓는 것을 좋아한다.JSON 모드를 이해하려면 this 및 this를 사용할 수 있습니다.이 두 개면 충분하다.
// app/models/schemas/book_payload.json
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"required": [ "title", "publisher", "published_date", "authors" ],
"properties": {
"title": { "type": "string" },
"publisher": { "type": "string" },
"published_date": { "type": "string" },
"authors": {
"type": "array",
"items": {
"$ref": "authors.json#/definitions/data"
},
"minItems": 1,
"uniqueItems": true
}
}
}
// app/models/schemas/authors.json
{
"definitions": {
"data": {
"type": "object",
"required": [ "id", "name" ],
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
}
}
}
}
그런 다음 Gemfile에 넣고 번들로 설치합니다.gem 'activerecord_json_validator'
그리고 우리는 우리의 모형을 갱신한다.(이 보석을 이해하려면 그들의 github page만으로도 충분하다.)# app/models/book.rb
class Book < ApplicationRecord
...
PAYLOAD_SCHEMA = "#{Rails.root}/app/models/schemas/book_payload.json"
validates :payload, presence: true, json: { message -> (err) { err }, schema: PAYLOAD_SCHEMA }
end
첫 번째 단계는 완성이다.이제 다음 코드를 보십시오.book_payload = {
title: 'Getting to Plan B',
pubs: 'Harvard Business Review Press',
authors: 'John W Mullins'
rating: 3.5
}
Book.create!(user_id: 1, payload: book_payload)
위의 코드는 json이 잘못되었기 때문에 검증 오류를 던질 것입니다.없음publisher
param, 없음publisher_date
param, 그리고 authors
param은 그룹이 아닙니다.다음 코드를 살펴보십시오.
book_payload = {
title: 'Getting to Plan B',
publisher: 'Harvard Business Review Press',
published_date: '2009-09-08',
pubs: 'Harvard Business Review Press',
authors: [
{
id: 3,
name: 'John W Mullins',
web: 'http://www.johnwmullins.com'
}
],
rating: 4.2
}
Book.create!(user_id: 1, payload: book_payload)
위의 코드는 검증 오류를 일으키지 않습니다!왜냐하면 그것은 효과적인 json이기 때문이다.너도 pubs
하고 rating
!Book.last.payload['pubs']
# => "Harvard Business Review Press"
Book.last.payload['rating']
# => 4.2
Book.last.payload['authors'][0]['web']
# => "http://www.johnwmullins.com"
만약 API 소비자가 모든 요청에 100개의 파라미터를 제공한다면, 당신의 데이터 저장소는 당신이 영원히 필요로 하지 않는 쓰레기를 처리하는 데 사용될 것입니다.이것이 바로 우리가 화이트리스트 파라미터를 필요로 하는 이유다.
두 번째 단계는 컨트롤러에서 백명단 파라미터를 표시합니다.이것은 JSONB 열 유형뿐만 아니라 다른 열 유형에도 필요합니다.
디렉터를 업데이트합니다.
# app/controllers/books_controller.rb
class BooksController < ApplicationController
def create
book = Book.create!(book_params)
render json: { status: "OK", message: "Book created!", object: book }, status: 201
end
private
def book_params
params.permit(
payload: [
:title,
:publisher,
:published_date,
authors: [
:id,
:name
]
]
)
end
end
너는 화이트리스트 파라미터가 어떻게 작동하는지 안다.나는 위의 코드를 설명할 필요가 없다고 생각한다.이렇게현재, jsonb열을 검증했습니다.
5. 업데이트
Note: All of the examples in this chapter are assuming you don't have validation for
payload
column inBook
.
JSONB 열을 업데이트하는 것은 좀 까다롭다.만약 네가 이 책의 마지막 기록의 제목만 바꾸고 싶다면.하면, 만약, 만약...
Book.last.payload
# => {"title"=>"Hacking Growth", "publisher"=>"Currency", "published_date"=>"2017-04-07", "authors"=>[{"id"=>1, "name"=>"Sean Ellis"}, {"id"=>2, "name"=>"Morgan Brown"}]}
book_payload = {
title: 'Blue Ocean'
}
Book.last.update(payload: book_payload)
지금 너의 payload
는 title
만 포함된다!Book.last.payload
# => {"title"=>"Blue Ocean"}
Book.last.payload['publisher']
# => nil
Book.last.payload['authors']
# => nil
올바른 방법:book = Book.last
book.payload['title'] = 'Blue Ocean'
book.save!
Book.last.payload
# => {"title"=>"Blue Ocean", "publisher"=>"Currency", "published_date"=>"2017-04-07", "authors"=>[{"id"=>1, "name"=>"Sean Ellis"}, {"id"=>2, "name"=>"Morgan Brown"}]}
JSONB 열에 대한 프롬프트를 업데이트하려면 다음과 같이 하십시오.# app/controllers/books_controller.rb
class BooksController < ApplicationController
def update
UpdateBookPayload.new(update_params).call
render json: { status: "OK", message: "Book updated!" }, status: 200
end
private
def update_params
params.permit(
:book_id,
:title,
:publisher,
:published_date,
authors: [
:id,
:name
]
)
end
end
# app/lib/update_book_payload.rb
class UpdateBookPayload
def initialize(params)
@params = params
@book = book
end
def call
iterate_params
@book.save!
end
private
def book
Book.find(@params[:book_id])
end
def iterate_params
params = @params.delete('book_id')
params.each do |key1, value1|
if key1 == 'authors'
iterate_authors(key1, value1)
else
@book.payload[key1] = (value1 || @book.payload[key1])
end
end
end
def iterate_authors(key1, value1)
value1.each_with_index do |value2, key2|
value2.each do |key3, value3|
@book.payload[key1][key2][key3] = (value3 || @book.payload[key1][key2][key3])
end
end
end
end
따라서 API 사용자는 모든 json을 사용자에게 전달할 수 있습니다.rails 콘솔을 사용하여 perform에서 클래스를 확인할 수 있습니다.Book.last.id
# => 10
Book.last.payload
# => {"title"=>"Hacking Growth", "publisher"=>"Currency", "published_date"=>"2017-04-07", "authors"=>[{"id"=>1, "name"=>"Sean Ellis"}, {"id"=>2, "name"=>"Morgan Brown"}]}
params = {
book_id: 10,
title: 'Blue Ocean',
authors: [
{},
{ id: 5 }
]
}
UpdateBookPayload.new(params).call
Book.last.payload
# => {"title"=>"Blue Ocean", "publisher"=>"Currency", "published_date"=>"2017-04-07", "authors"=>[{"id"=>1, "name"=>"Sean Ellis"}, {"id"=>5, "name"=>"Morgan Brown"}]}
6. 마지막 한마디
이것은 첫 번째 부분의 결말이다.제2부분에서 저는
store_accessor
, 조회와 인덱스를 소개할 것입니다.자료 출처: 나 자신과 많은 자료의 발췌문, 나는 그것들을 보존하지 않는다. 나는 내가 기억하는 것만 쓴다.
Reference
이 문제에 관하여(Rails+PostgreSQL JSONB(섹션 1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/kputra/rails-postgresql-jsonb-part-1-4ibg텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)