컨텍스트에 따라 다른 ActiveRecord 유효성 검사 실행

7712 단어 webdevrailsruby
때때로 데이터베이스 모델에 대한 특정 유효성 검사를 건너뛰고 싶을 수 있습니다. 다단계 마법사가 있거나 관리자가 더 자유롭게 데이터를 변경하기를 원할 수 있습니다.

특정 양식이 유효성 검사를 건너뛰게 하고 싶을 수도 있지만 더 좋은 방법이 있습니다.

Rails를 사용하면 레코드를 저장하거나 유효성을 검사할 때 context를 전달할 수 있습니다. contexton: 옵션과 결합하여 특정 ActiveRecord 유효성 검사만 실행할 수 있습니다.

용법



구인 게시판을 위한 다단계 워크플로를 만들고 싶다고 가정해 보겠습니다. 누군가가 작업 목록을 작성하고 데이터 채우기를 시작하도록 허용할 수 있지만 목록을 게시할 때까지 모든 것을 완전히 검증하지는 않습니다.

class Listing < ApplicationRecord
  belongs_to :company
  belongs_to :user

  has_rich_text :requirements

  validates :title, presence: true, length: { maximum: 50 }

  validates :salary_range, presence: true, on: :publish
  validates :application_instructions, presence: true, on: :publish

  def publish!
    self.published_at = Time.current
    save(context: :publish)
  end
end


이 경우 이 레코드를 생성하거나 편집할 때마다 항상 title(최대 50자)가 필요합니다. 그러나 유효성 검사 컨텍스트로 salary_range를 전달할 때만 application_instructions:publish의 유효성을 검사합니다.

다음과 같은 컨트롤러 작업으로 이 워크플로를 구현할 수 있습니다.

class ListingsController < ApplicationController

  def create
    @listing = Listing.new(listing_params)

    if @listing.save
      redirect_to @listing, notice: "Listing created"
    else
      render :new, status: :unprocessable_entity
    end
  end

  def publish
    @listing = Listing.find(params[:id])

    if @listing.publish!
      redirect_to @listing, notice: "Listing published"
    else
      render :edit, status: :unprocessable_entity
    end
  end
end


어떤 사용자가 변경하는지에 따라 다른 유효성 검사를 추가할 수도 있습니다. 관리자가 친구에게 특별하고 짧은 사용자 이름을 부여하도록 허용하고 싶을 수도 있습니다.

여기에서 :create 컨텍스트(Rails가 레코드를 생성할 때 기본적으로 포함함)에서 6자의 사용자 이름을 요구하는 하나의 규칙을 설정할 수 있습니다. 그런 다음 :admin 컨텍스트에 3자만 필요한 규칙을 추가합니다.

class Account < ApplicationRecord
  validates :username, length: { minimum: 6 }, on: :create
  validates :username, length: { minimum: 3 }, on: :admin
end

Account.new(username: "swanson").valid? # => true
Account.new(username: "swanson").valid?(:admin) # => true

Account.new(username: "mds").valid? # => false
Account.new(username: "mds").valid?(:admin) # => true

Account.new(username: "a").valid? # => false
Account.new(username: "a").valid?(:admin) # => false


Rails 유효성 검사 컨텍스트를 사용할 때의 한 가지 단점은 데이터베이스 수준 유효성 검사를 사용하지 못할 수 있다는 것입니다. 부분적으로 유효한 레코드를 유지하거나 조건부 규칙을 가질 수 있다는 것은 강력한 기능이지만 비용이 없는 것은 아닙니다.

데이터베이스 제약 수준에서 응용 프로그램으로 유효성 검사를 이동하는 것에 대해 신중하게 생각하십시오.

추가 리소스



레일 가이드: Validations :on option

Rails API 문서: ActiveRecord::Validations#valid?

좋은 웹페이지 즐겨찾기