복붙노트

[RUBY-ON-RAILS] 어떻게 레일 액티브의 모델의 속성에 대한 기본값을 만들려면 어떻게해야합니까? [복제]

RUBY-ON-RAILS

어떻게 레일 액티브의 모델의 속성에 대한 기본값을 만들려면 어떻게해야합니까? [복제]

나는 액티브 그것을 정의하여 속성에 대한 기본값을 만들려고합니다. 상태 : 레코드가 생성됩니다 기본적 때마다, 나는 속성에 대해 디폴트 값을 갖고 싶어. 나는이 작업을 수행하려고 :

class Task < ActiveRecord::Base
  def status=(status)
    status = 'P'
    write_attribute(:status, status)
  end
end

그러나 창조에 난 여전히 데이터베이스에서이 오류를 검색 :

ActiveRecord::StatementInvalid: Mysql::Error: Column 'status' cannot be null

그러므로 나는 값이 속성에 적용되지 않았습니다 추정.

레일에서이 작업을 수행 할 수있는 우아한 방법이 있을까요?

많은 감사합니다.

해결법

  1. ==============================

    1.당신은 이전의 열의 기본 옵션을 설정할 수 있습니다

    당신은 이전의 열의 기본 옵션을 설정할 수 있습니다

    ....
    add_column :status, :string, :default => "P"
    ....
    

    또는

    당신은 콜백, before_save을 사용할 수 있습니다

    class Task < ActiveRecord::Base
      before_save :default_values
      def default_values
        self.status ||= 'P' # note self.status = 'P' if self.status.nil? might be safer (per @frontendbeauty)
      end
    end
    
  2. ==============================

    2.나는 약간의 차이가이 문제를 바로 얼마 전에 조금, 그리고 레일 3.0에 대한 옵션을 발생하기 때문에, 나는이 질문에 다른 대답을 제공 할 수 있습니다.

    나는 약간의 차이가이 문제를 바로 얼마 전에 조금, 그리고 레일 3.0에 대한 옵션을 발생하기 때문에, 나는이 질문에 다른 대답을 제공 할 수 있습니다.

    레일 3.0에서는 이런 일을하고 싶지 :

    class MyModel < ActiveRecord::Base
      after_initialize :default_values
    
      private
        def default_values
          self.name ||= "default value"
        end
    end
    
  3. ==============================

    3.나는 새로운 기록을 위해 일반적으로 값의 기본 필요하면 새로운 액션의 뷰가 렌더링되기 전에. 양식을 렌더링 할 때 그들이 사용할 수 있도록 다음 메서드는 새 레코드의 기본 값을 설정합니다. before_save 및 before_create 너무 늦게 당신이 기본 값이 입력 필드에 표시하려는 경우 작동하지 않습니다.

    나는 새로운 기록을 위해 일반적으로 값의 기본 필요하면 새로운 액션의 뷰가 렌더링되기 전에. 양식을 렌더링 할 때 그들이 사용할 수 있도록 다음 메서드는 새 레코드의 기본 값을 설정합니다. before_save 및 before_create 너무 늦게 당신이 기본 값이 입력 필드에 표시하려는 경우 작동하지 않습니다.

    after_initialize do
      if self.new_record?
        # values will be available for new record forms.
        self.status = 'P'
        self.featured = true
      end
    end
    
  4. ==============================

    4.당신은 전혀 코드를 작성 : 당신은 단지 데이터베이스의 컬럼에 대한 기본 값을 설정할 필요가없이 그것을 할 수 있습니다. 당신은 당신의 마이그레이션에이 작업을 수행 할 수 있습니다. 예를 들면 :

    당신은 전혀 코드를 작성 : 당신은 단지 데이터베이스의 컬럼에 대한 기본 값을 설정할 필요가없이 그것을 할 수 있습니다. 당신은 당신의 마이그레이션에이 작업을 수행 할 수 있습니다. 예를 들면 :

    create_table :projects do |t|
      t.string :status, :null => false, :default => 'P'
      ...
      t.timestamps
    end
    

    희망이 도움이.

  5. ==============================

    5.이 솔루션은 몇 가지에 달려있다.

    이 솔루션은 몇 가지에 달려있다.

    기본값은 작성시 사용할 수있는 다른 정보에 의존? 당신은 최소한의 결과로 데이터베이스를 닦아 수 있습니까?

    첫 번째 질문에 대답하는 경우 예, 당신은 짐의 솔루션을 사용하려면

    두 번째 질문에 대답하는 경우 예, 당신은 다니엘의 솔루션을 사용하려면

    당신이 두 질문에 아무 대답하면, 당신은 아마 더 추가하고 새로운 마이그레이션을 실행하는 길 이죠 없습니다.

    class AddDefaultMigration < ActiveRecord::Migration
      def self.up
         change_column :tasks, :status, :string, :default => default_value, :null => false
      end
    end
    

    : 문자열은 액티브 :: 마이그레이션 인식하는 어떤 종류로 교체 할 수 있습니다.

    CPU는 짐의 솔루션에서 작업의 재정의 많은 문제가 발생하지 않을 수 있도록 저렴합니다. 특히 생산 환경이다. 이 마이그레이션은 그것을로드 훨씬 덜 자주 불리는 그 일을 적절한 방법입니다.

  6. ==============================

    6.나는 여기에있는 attr_defaults 사용을 고려한다. 귀하의 거칠은 꿈이 실현됩니다.

    나는 여기에있는 attr_defaults 사용을 고려한다. 귀하의 거칠은 꿈이 실현됩니다.

  7. ==============================

    7.그냥 짐의 답변을 강화

    그냥 짐의 답변을 강화

    현재 하나를 사용하여 수행 할 수 있습니다

    class Task < ActiveRecord::Base
      before_save :default_values
      def default_values
        self.status = status.presence || 'P'
      end
    end
    
  8. ==============================

    8.이 질문에 문자열처럼 - - 열 유형 상자에서 지원을 레일 가장 좋은 방법은 다니엘 크리스텐센은 표시대로 데이터베이스 자체를 열 기본값을 설정하는 것입니다. 레일은 DB의 인트로 따라 객체를 초기화합니다. 게다가, 그 누군가가 당신의 레일 응용 프로그램의 행 외부를 추가하고 해당 열을 초기화 잊어에서 DB의 안전을합니다.

    이 질문에 문자열처럼 - - 열 유형 상자에서 지원을 레일 가장 좋은 방법은 다니엘 크리스텐센은 표시대로 데이터베이스 자체를 열 기본값을 설정하는 것입니다. 레일은 DB의 인트로 따라 객체를 초기화합니다. 게다가, 그 누군가가 당신의 레일 응용 프로그램의 행 외부를 추가하고 해당 열을 초기화 잊어에서 DB의 안전을합니다.

    열 유형 상자 밖으로 지원하지 않습니다 레일 - 예를 ENUM 컬럼 - 레일은 열 기본을 성찰 할 수 없습니다. 이런 경우 당신은 before_create (가 검증 한 후에 발생하기 때문에) 또는 before_save (때문에 (이 객체가 모든 객체가 .new를 사용하여 생성되는 시간뿐만 아니라 DB에서로드 될 때마다 호출) after_initialize을 사용하지 않으 ) 당신이 원하는 일반적으로하지 않은, 너무 업데이 트에 발생합니다.

    과 같이 작성 : 오히려, 당신은에 before_validation에 속성을 설정할 :

    before_validation :set_status_because_rails_cannot, on: :create
    
    def set_status_because_rails_cannot
      self.status ||= 'P'
    end
    
  9. ==============================

    9.내가 그것을보고, 디폴트 값을 필요로 할 때 주소 필요 두 가지 문제가있다.

    내가 그것을보고, 디폴트 값을 필요로 할 때 주소 필요 두 가지 문제가있다.

    여기 내 솔루션입니다 :

    # the reader providers a default if nil
    # but this wont work when saved
    def status
      read_attribute(:status) || "P"
    end
    
    # so, define a before_validation callback
    before_validation :set_defaults
    protected
    def set_defaults
      # if a non-default status has been assigned, it will remain
      # if no value has been assigned, the reader will return the default and assign it
      # this keeps the default logic DRY
      status = status
    end
    

    나는 사람들이이 방법을 생각 이유를 알고 싶네요.

  10. ==============================

    10.내가 지금 할 수있는 더 좋은 방법을 발견 :

    내가 지금 할 수있는 더 좋은 방법을 발견 :

    def status=(value) 
      self[:status] = 'P' 
    end 
    

    루비에서 메서드 호출 그렇지 않으면 루비 메서드 호출로 인식한다, 그러므로 나는 다른 무언가에 지역 변수 이름을 지정해야, 어떤 괄호가없는 허용된다.

  11. from https://stackoverflow.com/questions/1550688/how-do-i-create-a-default-value-for-attributes-in-rails-activerecords-model by cc-by-sa and MIT license