Rails 1.2 RC1의 ActiveRecord에 새로 추가된 기능들

Rails 1.2 Release Candidate 1이 나왔습니다!란 글을 올린 후로 Riding Rails 공식 블로그에는 1.2에 새로 추가된 기능들에 대한 글이 올라오고 있습니다.

모두 정확히 설명하기에는 저의 능력이 많이 부족하지만, 하나하나 살펴보도록 하겠습니다. 오늘은 우선 ActiveRecord에 새로 추가된 기능들을 살펴보겠습니다.

1. Finding

해시를 이용한 Find conditions

AR에서 가장 유용하면서도 강력하고 자주 사용하게 되는 find 메소드에 편리한 기능이 추가되었습니다.
Person.find(:all, :conditions => [ "last_name = ? and status = ?", "Catlin", 1 ])
와 같이 써야했던 코드를 다음과 같이 이쁘게 작성할 수 있습니다.
Person.find(:all, :conditions => { :last_name => "Catlin", :status => 1 })
훨 씬 더 보기 좋지 않나요? 이 새로운 기능의 강력함은 여러가지 조건을 복잡하게 만족해서 리스트를 보여줘야하는 코드에 매우 유용하게 사용할 수 있습니다. "last_name = ? and status = ?" 와 같이 되어있는 부분을 작성하기 위해 last_name = ? 이라는 문자열과 status = ?라는 문자열을 경우에 따라 합치거나 빼줘야하는 지저분한 코드를 써야할 경우 새로운 기능을 통해 해시로 넘길 경우에는
cond =  {}
cond[:last_name] = "Catlin"
cond[:status] = 1
Person.find(:all, :conditions => cond)
와 같이 작성할 수 있게 됩니다. 물론 오직 AND 연산으로 묶어주기 때문에 복잡한 조건을 쓸 수는 없지만, 많은 부분에서 코드를 간결하게 만들어 줄 것입니다.

find_or_initialize_by_x
예 전에는 Tag.find_or_create_by_name("Ruby")와 같이 해당 값이 없는 경우 생성해주는 기능이 있었습니다. tag를 붙이는 기능에 많이 사용되었습니다. create라는 단어에서도 암시하듯 저 메소드를 생성할 경우 DB에 저장을 하게 됩니다만, Rails 1.2부터는 Tag,find_or_initialize_by_name("Ruby")와 같은 방법을 통해 DB에는 저장하지 않고 AR객체를 사용할 수 있게 되었습니다.

:conditions의 매개변수로서 ActiveRecord Object가 id값으로
예전에는
Foo.find(:all, :conditions => ['bar_id IN (?)', bars])
와 같이 사용하기 위해서는 bars가 [1,2,3] 과 같이 배열 id를 갖고 있어야 했습니다만, 지금은
bars = Bar.find(:all)
Foo.find(:all, :conditions => ['bar_id IN (?)', bars])
와 같이 AR객체(또는 배열)를 바로 변수로 넘겨줄 경우 id값을 넘겨주게 됩니다.

2. Associations

중복 값 제거하고 결과 받기
has_many :through에서 :uniq => true를 설정해 줄 경우 find를 통한 결과값에서 중복된 내용을 제거한 결과를 받을 수 있습니다.

has_many :through에서
# before:
post.taggings.create!(:tag => Tag.find_by_name('finally')
# after:
post.tags << Tag.find_by_name('finally')
에서 볼 수 있듯 has_many :through 모델을 좀 더 쉽게 다룰 수 있게 << 를 사용할 수 있군요.
# before:
transaction { post.taggings.create!(:tag => Tag.create!(:name => 'general')) }
# after:
post.tags.create! :name => 'general'
여기서는 좀 더 직관적이 되었습니다. has_many :through 모델을 더 애용할 수 있겠습니다. :)

has_many :through에도 delete메소드가
또한 has_many :through에 delete 메소드가 추가되었다고 합니다.

has_one에도 :dependent 속성을
has_one 에는 has_many처럼 :destroy, :delete, :nullify가 지원된다고 하니 foreign key를 좀 더 유용하게 사용할 수 있겠습니다. :destroy를 사용하고 foreign key가 걸려있는 경우 has_many에 의해 물려있는 여러개의 연관 데이터를 DB가 알아서 삭제해주게 됩니다. :delete를 사용할 경우 foreign key에 의해 DB가 알아서 연관 데이터를 삭제하는 것이 아니라 Rails가 연관 데이터를 삭제하는 SQL을 하나하나 다 보내게 됩니다. :nullify는 이름에서도 알 수 있듯이 연관 데이터를 지우지 않고 연결 고리만 삭제하는 것이지요.

그외

이외에도
Person.transaction do
  # SELECT * FROM people WHERE id=1 FOR UPDATE
  person = Person.find(1, :lock => true)
  person.visits += 1
  person.save!
end
에서 보듯이 데이터베이스 레코드의 한 레코드에만 lock을 걸 수 있게 되었군요. 다운로드 수나 글 읽은 수 등을 업데이트할 때 유용하게 쓰일 수 있겠습니다.


목차
  1. Rails 1.2 RC1의 ActiveRecord에 새로 추가된 기능들
  2. Rails 1.2 RC1의 ActionPack에 새로 추가된 기능들
  3. Rails 1.2 RC1의 ActiveSupport에 새로 추가된 기능들

by 정목 | 2006/11/28 02:10 | Ruby & Rails | 트랙백 | 덧글(4)
트랙백 주소 : http://niceview.egloos.com/tb/2843046
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 테이_ble at 2006/11/28 11:42
엄청 깔끔해지는 코드들.. 우호호...
Commented by 정목 at 2006/11/29 14:19
ㅎㅎ 쫓아가려면 열심히 들여다봐야겠어요~
Commented by 하길호 at 2006/12/11 15:05
제 카페에 목상님의 글을 올리고 싶은데
어떻게 생각하시는지요

잘 보고 갑니다. 그럼 ,, -,.-;
Commented by 정목 at 2006/12/12 18:35
출처만 잊지 않으신다면 괜찮습니다. :) 도움이 되었으면 좋겠네요. 그나저나 목상님은.. 설마 저를 두고 하시는 말씀이지요? :)
까페에 자료를 엄청 많이 모아두셨네요~ 자주 들르겠습니다~

:         :

:

비공개 덧글