복붙노트

[RUBY-ON-RAILS] 액티브에서 만든에서 ID를 재정의

RUBY-ON-RAILS

액티브에서 만든에서 ID를 재정의

생성에 모델의 id 값을 재정의 방법이 있습니까? 뭔가 같은 :

Post.create(:id => 10, :title => 'Test')

이상적인 것이지만, 분명히 작동하지 않습니다.

해결법

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

    1.ID는 단지 당신이 그것을 설정하는 대량 할당을 사용할 수없는 이유입니다, attr_protected된다. 수동으로 설정할 때, 그냥 작동합니다 :

    ID는 단지 당신이 그것을 설정하는 대량 할당을 사용할 수없는 이유입니다, attr_protected된다. 수동으로 설정할 때, 그냥 작동합니다 :

    o = SomeObject.new
    o.id = 8888
    o.save!
    o.reload.id # => 8888
    

    나는 확실하지 원래의 동기가 무엇인지 합니다만, 액티브에 ActiveHash 모델을 변환 할 때 나는이 작업을 수행. ActiveHash는 액티브 동일한 belongs_to 의미를 사용할 수 있습니다, 대신 마이그레이션을 갖는 테이블을 생성하고 모든 호출에 데이터베이스의 오버 헤드를, 당신은 단지 YML 파일에 데이터를 저장합니다. 데이터베이스의 외래 키는 YML의 메모리 ID를 참조합니다.

    ActiveHash 변화가 자주 만 개발자에 의해 변경하는 것이 선택 목록 및 작은 테이블에 좋은 곳입니다. 액티브에 ActiveHash에서 갈 때, 그것은 단지 외부 키 참조 같은 모든 유지하는 가장 쉬운 방법.

  2. ==============================

    2.시험

    시험

    a_post = Post.new do |p| 
      p.id = 10
      p.title = 'Test'
      p.save
    end
    

    그것은 당신이 찾고있는 무엇을 제공해야합니다.

  3. ==============================

    3.당신은 또한이 같은 것을 사용할 수 있습니다 :

    당신은 또한이 같은 것을 사용할 수 있습니다 :

    Post.create({:id => 10, :title => 'Test'}, :without_protection => true)
    

    워드 프로세서에 명시된 바와 같이하지만,이 의지 바이 패스 대량 할당 보안을 제공합니다.

  4. ==============================

    4.레일 4 :

    레일 4 :

    Post.create(:title => 'Test').update_column(:id, 10)
    

    다른 레일 4 대답은 나를 위해 작동하지 않았다. 레일 콘솔을 사용하여 검사 할 때 그들 중 많은 사람들이 변화에 등장하지만 MySQL 데이터베이스의 값을 확인할 때, 그들은 변화가 없었다. 다른 답변은 가끔했다.

    당신이 update_column 사용하지 않는 MySQL을위한 최소한의 자동 증가 ID 번호 아래에 ID를 할당하는 작업을하지 않습니다. 예를 들어,

    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
    

    당신이 변경하면 여전히이 문제가됩니다 저장 새 +를 사용하여 만들 수 있습니다. 수동 p.id = 10과 같은 ID를 변경하면이 문제를 생산하고 있습니다.

    그것은 별도의 데이터베이스 쿼리 비용에도 불구하고이 항상 작동하기 때문에 일반적으로, 나는 ID를 변경 update_column 사용할 수 있습니다. 이 개발 환경에 표시되지 않을 수도 있습니다 오류가 발생 할 수 있지만, 조용히을 손상 프로덕션 데이터베이스의 모든 말을하면서 노력하고 있습니다.

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

    5.사실, 그것은 다음과 같은 일을하고있는 것으로 나타났다 :

    사실, 그것은 다음과 같은 일을하고있는 것으로 나타났다 :

    p = Post.new(:id => 10, :title => 'Test')
    p.save(false)
    
  6. ==============================

    6.제프가 지적 하듯이, 마치 아이디 동작합니다은 attr_protected된다. 그것을 방지하기 위해, 당신은 기본적으로 보호 된 속성의 목록을 오버라이드 (override) 할 필요가있다. 속성 정보가 외부에서 올 수 있음이 어디 일을주의해야합니다. ID 필드는 이유로 보호 기본값입니다.

    제프가 지적 하듯이, 마치 아이디 동작합니다은 attr_protected된다. 그것을 방지하기 위해, 당신은 기본적으로 보호 된 속성의 목록을 오버라이드 (override) 할 필요가있다. 속성 정보가 외부에서 올 수 있음이 어디 일을주의해야합니다. ID 필드는 이유로 보호 기본값입니다.

    class Post < ActiveRecord::Base
    
      private
    
      def attributes_protected_by_default
        []
      end
    end
    

    (액티브 레코드 2.3.5 테스트 수단)

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

    7.우리는 attributes_protected_by_default 대체 할 수 있습니다

    우리는 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)
    
  8. ==============================

    8.

    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
    
  9. ==============================

    9.명시 적 ID가 요구되는 개체 생성을 수행하는 데 사용할 다음 seeds.rb의 상단이 create_with_id 기능을 넣어.

    명시 적 ID가 요구되는 개체 생성을 수행하는 데 사용할 다음 seeds.rb의 상단이 create_with_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, 이름 : "내 푸", 소품 : "내 다른 재산"})

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

    10.이 경우는 지정 날짜의 종류와 ID를 덮어 쓰기 필요했다 유사한 문제입니다 :

    이 경우는 지정 날짜의 종류와 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">
    

    콜백 잘 작동합니다.

    행운을 빕니다!.

  11. ==============================

    11.레일 3의 경우,이 작업을 수행하는 가장 간단한 방법은 저장 후 그리고, without_protection 정제와 새로운 사용하는 것입니다 :

    레일 3의 경우,이 작업을 수행하는 가장 간단한 방법은 저장 후 그리고, without_protection 정제와 새로운 사용하는 것입니다 :

    Post.new({:id => 10, :title => 'Test'}, :without_protection => true).save
    

    종자 데이터의 경우, 그것은 당신이 이런 식으로 할 수있는 바이 패스 검증에 의미가 있습니다 :

    Post.new({:id => 10, :title => 'Test'}, :without_protection => true).save(validate: false)
    

    우리는 실제로 씨앗 파일을 실행하기 직전에 선언 된 액티브 :: 자료에 도우미 메서드를 추가했습니다 :

    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')
    

    레일 4를 들어, StrongParams 대신 보호 속성을 사용한다. 이 경우, 당신은 단순히 새로운 모든 플래그를 통과하지 않고 할당하고 저장 할 수 있습니다 :

    Post.new(id: 10, title: 'Test').save      # optionally pass `{validate: false}`
    
  12. ==============================

    12.PostgreSQL을 9.5.3와 레일 4.2.1에서 Post.create는 (: ID => 10 : 제목 => '테스트')만큼 이미 ID = 10 행이 아니므로 작동합니다.

    PostgreSQL을 9.5.3와 레일 4.2.1에서 Post.create는 (: ID => 10 : 제목 => '테스트')만큼 이미 ID = 10 행이 아니므로 작동합니다.

  13. ==============================

    13.당신은 SQL에 의해 ID를 삽입 할 수 있습니다 :

    당신은 SQL에 의해 ID를 삽입 할 수 있습니다 :

      arr = record_line.strip.split(",")
      sql = "insert into records(id, created_at, updated_at, count, type_id, cycle, date) values(#{arr[0]},#{arr[1]},#{arr[2]},#{arr[3]},#{arr[4]},#{arr[5]},#{arr[6]})"
      ActiveRecord::Base.connection.execute sql
    
  14. from https://stackoverflow.com/questions/431617/overriding-id-on-create-in-activerecord by cc-by-sa and MIT license