[ruby-on-rails] Rails에서 기본값을 설정하는 방법은 무엇입니까?

Rails에서 객체의 기본값을 설정하는 가장 좋은 방법을 찾으려고합니다.

내가 생각할 수있는 최선의 new방법은 컨트롤러 의 메서드에서 기본값을 설정하는 것입니다 .

이것이 수용 가능하거나 더 나은 방법이 있다면 누구든지 의견을 가지고 있습니까?



답변

“정답”은 Ruby에서 위험한 단어입니다. 일반적으로 하나 이상의 방법이 있습니다. 해당 테이블의 해당 열에 대해 항상 기본값을 원한다는 것을 알고 있다면 DB 마이그레이션 파일에서 설정하는 것이 가장 쉬운 방법입니다.

class SetDefault < ActiveRecord::Migration
  def self.up
    change_column :people, :last_name, :type, :default => "Doe"
  end

  def self.down
    # You can't currently remove default values in Rails
    raise ActiveRecord::IrreversibleMigration, "Can't remove the default"
  end
end

ActiveRecord는 테이블 및 열 속성을 자동 검색하기 때문에 표준 Rails 앱에서 사용하는 모든 모델에서 동일한 기본값이 설정됩니다.

그러나 특정 경우에만 기본값을 설정하려는 경우 (예 : 다른 테이블과 테이블을 공유하는 상속 된 모델) 다른 우아한 방법은 모델 객체가 생성 될 때 Rails 코드에서 직접 수행하는 것입니다.

class GenericPerson < Person
  def initialize(attributes=nil)
    attr_with_defaults = {:last_name => "Doe"}.merge(attributes)
    super(attr_with_defaults)
  end
end

그런 다음을 수행 할 때 다른 항목으로 재정의하지 않는 한 GenericPerson.new()항상 “Doe”속성을 조금씩 떨어 뜨 Person.new()립니다.


답변

SFEley의 답변을 기반으로 다음은 최신 Rails 버전에 대한 업데이트 / 수정 된 것입니다.

class SetDefault < ActiveRecord::Migration
  def change
    change_column :table_name, :column_name, :type, default: "Your value"
  end
end


답변

우선 initialize(*args)모든 경우에 호출 되지 않으므로 오버로드 할 수 없습니다 .

가장 좋은 방법은 기본값을 마이그레이션에 적용하는 것입니다.

add_column :accounts, :max_users, :integer, :default => 10

두 번째로 좋은 방법은 기본값을 모델에 배치하는 것이지만 처음에는 nil 인 속성에서만 작동합니다. boolean열에서 했던 것처럼 문제가있을 수 있습니다 .

def after_initialize
  if new_record?
    max_users ||= 10
  end
end

new_record?기본값이 데이터베이스에서로드 된 값을 재정의하지 않도록하기 위해 필요합니다 .

||=Rails가 initialize 메소드에 전달 된 매개 변수를 재정의하지 못하도록 해야 합니다.


답변

change_column_default마이그레이션을 시도 할 수도 있습니다 (Rails 3.2.8에서 테스트 됨).

class SetDefault < ActiveRecord::Migration
  def up
    # Set default value
    change_column_default :people, :last_name, "Smith"
  end

  def down
    # Remove default
    change_column_default :people, :last_name, nil
  end
end

change_column_default Rails API 문서


답변

ActiveRecord 객체를 참조하는 경우 다음 두 가지 방법이 있습니다.

1. DB에서 : default 매개 변수 사용

EG

class AddSsl < ActiveRecord::Migration
  def self.up
    add_column :accounts, :ssl_enabled, :boolean, :default => true
  end

  def self.down
    remove_column :accounts, :ssl_enabled
  end
end

자세한 정보 : http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

2. 콜백 사용

EG before_validation_on_create

자세한 정보 : http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M002147


답변

Ruby on Rails v3.2.8에서는 after_initializeActiveRecord 콜백을 사용하여 새 개체에 대한 기본값을 할당하는 모델의 메서드를 호출 할 수 있습니다.

after_initialize 콜백은 파인더에 의해 발견되고 인스턴스화 된 각 객체에 대해 트리거되며, after_initialize는 새 객체가 인스턴스화 된 후에도 트리거됩니다 ( ActiveRecord 콜백 참조 ).

따라서 IMO는 다음과 같이 보일 것입니다.

class Foo < ActiveRecord::Base
  after_initialize :assign_defaults_on_new_Foo
  ...
  attr_accessible :bar
  ...
  private
  def assign_defaults_on_new_Foo
    # required to check an attribute for existence to weed out existing records
    self.bar = default_value unless self.attribute_whose_presence_has_been_validated
  end
end

Foo.bar = default_value인스턴스에 attribute_whose_presence_has_been_validated이전 저장 / 업데이트 가 포함되어 있지 않은 경우이 인스턴스의 경우 . 는 default_value다음을 사용하여 폼 렌더링 할 뷰와 함께 사용됩니다 default_value에 대한 bar속성을.

기껏해야 해키입니다 …

편집- ‘new_record?’사용 새 호출에서 인스턴스화하는지 확인하려면

속성 값을 확인하는 대신 new_record? 레일과 함께 기본 제공 방법을 . 따라서 위의 예는 다음과 같습니다.

class Foo < ActiveRecord::Base
  after_initialize :assign_defaults_on_new_Foo, if: 'new_record?'
  ...
  attr_accessible :bar
  ...
  private
  def assign_defaults_on_new_Foo
    self.bar = default_value
  end
end

이것은 훨씬 더 깨끗합니다. 아, Rails의 마법-나보다 똑똑합니다.


답변

적어도 Rails 3.2.6의 부울 필드의 경우 마이그레이션에서 작동합니다.

def change
  add_column :users, :eula_accepted, :boolean, default: false
end

퍼팅 1또는 0그 부울 필드이기 때문에 기본값으로, 여기에 작동하지 않습니다. true또는 false값 이어야합니다 .