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
답변
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_initialize
ActiveRecord 콜백을 사용하여 새 개체에 대한 기본값을 할당하는 모델의 메서드를 호출 할 수 있습니다.
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
값 이어야합니다 .