[ruby-on-rails] ActiveRecord 콜백을 실행하지 않으려면 어떻게해야합니까?
after_save 콜백이있는 모델이 있습니다. 일반적으로 문제는 없지만 개발 데이터를 만들 때와 같은 일부 상황에서는 콜백을 실행하지 않고 모델을 저장하려고합니다. 그렇게하는 간단한 방법이 있습니까? 비슷한 것 …
Person#save( :run_callbacks => false )
또는
Person#save_without_callbacks
Rails 문서를 보았는데 아무것도 찾지 못했습니다. 그러나 내 경험상 Rails 문서가 항상 전체 이야기를 말하는 것은 아닙니다.
최신 정보
다음 과 같은 모델에서 콜백을 제거하는 방법을 설명하는 블로그 게시물 을 찾았 습니다 .
Foo.after_save.clear
그 방법이 문서화 된 곳을 찾을 수 없지만 작동하는 것 같습니다.
답변
이 솔루션은 Rails 2 전용입니다.
방금 조사한 결과 해결책이 있다고 생각합니다. 사용할 수있는 두 가지 ActiveRecord 개인용 메소드가 있습니다.
update_without_callbacks
create_without_callbacks
이러한 메소드를 호출하려면 send를 사용해야합니다. 예 :
p = Person.new(:name => 'foo')
p.send(:create_without_callbacks)
p = Person.find(1)
p.send(:update_without_callbacks)
이것은 확실히 콘솔에서만 또는 임의의 테스트를 수행하는 동안 사용하고 싶은 것입니다. 도움이 되었기를 바랍니다!
답변
사용 update_column
(레일> = 3.1) 또는 update_columns
(레일> = 4.0) 콜백 및 유효성 검사를 건너 뜁니다. 또한 이러한 방법으로, updated_at
되어 있지 업데이트되었습니다.
#Rails >= v3.1 only
@person.update_column(:some_attribute, 'value')
#Rails >= v4.0 only
@person.update_columns(attributes)
http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column
# 2 : 객체를 만드는 동안 작동하는 콜백 건너 뛰기
class Person < ActiveRecord::Base
attr_accessor :skip_some_callbacks
before_validation :do_something
after_validation :do_something_else
skip_callback :validation, :before, :do_something, if: :skip_some_callbacks
skip_callback :validation, :after, :do_something_else, if: :skip_some_callbacks
end
person = Person.new(person_params)
person.skip_some_callbacks = true
person.save
답변
업데이트 :
@Vikrant Chaudhary의 솔루션이 더 좋아 보입니다.
#Rails >= v3.1 only
@person.update_column(:some_attribute, 'value')
#Rails >= v4.0 only
@person.update_columns(attributes)
내 원래 답변 :
이 링크 참조 : ActiveRecord 콜백을 건너 뛰는 방법?
Rails3에서
클래스 정의가 있다고 가정하십시오.
class User < ActiveRecord::Base
after_save :generate_nick_name
end
접근법 1 :
User.send(:create_without_callbacks)
User.send(:update_without_callbacks)
접근 방법 2 : rspec 파일이나 다른 파일에서 건너 뛰려면 다음을 시도하십시오.
User.skip_callback(:save, :after, :generate_nick_name)
User.create!()
참고 :이 작업이 완료되면 rspec 환경이 아닌 경우 콜백을 재설정해야합니다.
User.set_callback(:save, :after, :generate_nick_name)
레일 3.0.5에서 잘 작동합니다.
답변
레일 3 :
MyModel.send("_#{symbol}_callbacks") # list
MyModel.reset_callbacks symbol # reset
답변
콜백이나 유효성 검사없이 단순히 레코드를 삽입하는 것이 목표이며 추가 gem에 의존하지 않고 조건부 검사를 추가하거나 RAW SQL을 사용하거나 종료 코드를 사용하여 어떤 식 으로든 퍼징하지 않고 수행하려는 경우 “그림자”사용을 고려하십시오. 기존 DB 테이블을 가리키는 개체 ” 이렇게 :
class ImportedPerson < ActiveRecord::Base
self.table_name = 'people'
end
이것은 모든 Rails 버전에서 작동하며 스레드 안전하며 기존 코드를 수정하지 않고도 모든 유효성 검사 및 콜백을 완전히 제거합니다. 실제로 가져 오기 직전에 클래스 선언을 던질 수 있으며 잘 진행해야합니다. 다음과 같이 새 클래스를 사용하여 객체를 삽입하십시오.
ImportedPerson.new( person_attributes )
답변
Person 모델에서 다음과 같은 것을 시도해 볼 수 있습니다.
after_save :something_cool, :unless => :skip_callbacks
def skip_callbacks
ENV[RAILS_ENV] == 'development' # or something more complicated
end
편집 : after_save는 기호가 아니지만 적어도 1,000 번 시도했습니다.
답변
당신은 사용할 수 있습니다 update_columns
:
User.first.update_columns({:name => "sebastian", :age => 25})
save를 호출하지 않고 객체의 지정된 속성을 업데이트하므로 유효성 검사 및 콜백을 건너 뜁니다.