답변:
id는 attr_protected 뿐이므로 대량 할당을 사용하여 설정할 수 없습니다. 그러나 수동으로 설정하면 다음과 같이 작동합니다.
o = SomeObject.new
o.id = 8888
o.save!
o.reload.id # => 8888
원래 동기가 뭔지는 모르겠지만 ActiveHash 모델을 ActiveRecord로 변환 할 때 이렇게합니다. ActiveHash를 사용하면 ActiveRecord에서 동일한 belongs_to 시맨틱을 사용할 수 있지만 마이그레이션하고 테이블을 생성하고 모든 호출에서 데이터베이스 오버 헤드를 발생시키는 대신 yml 파일에 데이터를 저장하기 만하면됩니다. 데이터베이스의 외래 키는 yml의 메모리 내 ID를 참조합니다.
ActiveHash는 자주 변경되지 않고 개발자 만 변경하는 선택 목록 및 작은 테이블에 적합합니다. 따라서 ActiveHash에서 ActiveRecord로 이동할 때 모든 외래 키 참조를 동일하게 유지하는 것이 가장 쉽습니다.
ActiveRecord::VERSION::STRING == "3.2.11"여기에 (sqlite3 어댑터 사용) 위의 내용이 나를 위해 작동합니다.
시험
a_post = Post.new do |p|
p.id = 10
p.title = 'Test'
p.save
end
그것은 당신이 찾고있는 것을 당신에게 줄 것입니다.
다음과 같이 사용할 수도 있습니다.
Post.create({:id => 10, :title => 'Test'}, :without_protection => true)
문서에 명시되어 있지만 이는 대량 할당 보안을 우회합니다.
Rails 4 :
Post.create(:title => 'Test').update_column(:id, 10)
다른 Rails 4 답변은 저에게 효과적 이지 않았습니다 . Rails Console을 사용하여 확인할 때 대부분 변경된 것처럼 보였지만 MySQL 데이터베이스에서 값을 확인했을 때 변경되지 않았습니다. 다른 답변은 때때로 효과가있었습니다.
최소한 MySQL의 경우를 사용하지 않는 한 id자동 증가 ID 번호 아래에 할당하면 작동 하지 않습니다update_column . 예를 들면
p = Post.create(:title => 'Test')
p.id
=> 20 # 20 was the id the auto increment gave it
p2 = Post.create(:id => 40, :title => 'Test')
p2.id
=> 40 # 40 > the next auto increment id (21) so allow it
p3 = Post.create(:id => 10, :title => 'Test')
p3.id
=> 10 # Go check your database, it may say 41.
# Assigning an id to a number below the next auto generated id will not update the db
+ create를 사용하도록 변경 하면 여전히이 문제가 발생합니다. 유사 항목을 수동으로 변경해도이 문제가 발생합니다.newsaveidp.id = 10
일반적으로 항상 작동하므로 추가 데이터베이스 쿼리가 필요하더라도 update_column변경하는 데 사용 합니다 id. 이것은 개발 환경에 표시되지 않을 수있는 오류이지만 작동 중이라고 말하면서 프로덕션 데이터베이스를 조용히 손상시킬 수 있습니다.
Post.new.update(id: 10, title: 'Test')
실제로 다음 작업을 수행하는 것으로 나타났습니다.
p = Post.new(:id => 10, :title => 'Test')
p.save(false)
validate: false단순히 통과하는 것이 아니라 통과해도 여전히 작동합니다 false. 그러나 여전히 보호 된 속성 문제가 발생합니다. 제 답변에서 설명한 것과는 별도의 방법이 있습니다.
attributes_protected_by_default를 재정의 할 수 있습니다.
class Example < ActiveRecord::Base
def self.attributes_protected_by_default
# default is ["id", "type"]
["type"]
end
end
e = Example.new(:id => 10000)
Post.create!(:title => "Test") { |t| t.id = 10 }
이것은 당신이 일반적으로하고 싶은 일이라고 생각하지 않지만 고정 된 ID 세트로 테이블을 채워야하는 경우 (예를 들어 레이크 태스크를 사용하여 기본값을 생성 할 때) 꽤 잘 작동합니다. 자동 증가를 재정의하려는 경우 (작업을 실행할 때마다 테이블이 동일한 ID로 채워지도록) :
post_types.each_with_index do |post_type|
PostType.create!(:name => post_type) { |t| t.id = i + 1 }
end
이 create_with_id 함수를 seed.rb 상단에 배치 한 다음이를 사용하여 명시 적 ID가 필요한 객체 생성을 수행하십시오.
def create_with_id(clazz, params)
obj = clazz.send(:new, params)
obj.id = params[:id]
obj.save!
obj
end
이렇게 사용하세요
create_with_id( Foo, {id:1,name:"My Foo",prop:"My other property"})
사용하는 대신
Foo.create({id:1,name:"My Foo",prop:"My other property"})
이 경우는 id일종의 맞춤 날짜로 덮어 쓰는 데 필요한 유사한 문제입니다 .
# in app/models/calendar_block_group.rb
class CalendarBlockGroup < ActiveRecord::Base
...
before_validation :parse_id
def parse_id
self.id = self.date.strftime('%d%m%Y')
end
...
end
그리고 :
CalendarBlockGroup.create!(:date => Date.today)
# => #<CalendarBlockGroup id: 27072014, date: "2014-07-27", created_at: "2014-07-27 20:41:49", updated_at: "2014-07-27 20:41:49">
콜백이 제대로 작동합니다.
행운을 빕니다!.
idUnix 타임 스탬프를 기반으로 생성해야했습니다 . 나는 그것을 내부에서했다 before_create. 잘 작동합니다.
Rails 3의 경우이를 수행하는 가장 간단한 방법 new은 without_protection세분화 와 함께 사용 하고 다음을 수행하는 것입니다 save.
Post.new({:id => 10, :title => 'Test'}, :without_protection => true).save
시드 데이터의 경우 다음과 같이 수행 할 수있는 유효성 검사를 우회하는 것이 좋습니다.
Post.new({:id => 10, :title => 'Test'}, :without_protection => true).save(validate: false)
실제로 시드 파일을 실행하기 직전에 선언 된 ActiveRecord :: Base에 도우미 메서드를 추가했습니다.
class ActiveRecord::Base
def self.seed_create(attributes)
new(attributes, without_protection: true).save(validate: false)
end
end
그리고 지금:
Post.seed_create(:id => 10, :title => 'Test')
Rails 4의 경우 보호 된 속성 대신 StrongParams를 사용해야합니다. 이 경우 플래그를 전달하지 않고 간단히 할당하고 저장할 수 있습니다 new.
Post.new(id: 10, title: 'Test').save # optionally pass `{validate: false}`
{}위의 Samuel의 대답 (Rails3) 에 속성을 넣지 않고는 나를 위해 작동하지 않습니다 .
id아직 10입니다.
id10으로 전달되었으므로 정확히 그래야합니다. 예상했던 것이 아니라면 예를 들어 설명해 주시겠습니까?