Header

  1. View current page

    재선아빠님의 노트

Profile_image?t=1224119607&type=big
11

Railscasts

No1. Caching with instance variable

컨트롤러에서 모델의 find 메소드를 사용하는 경우 매번 DB 에 쿼리를 날리게 된다.

class ApplicationController < ActionController::Base

def current_user

User.find(session[:user_id])

@current_user ||= User.find(session[:user_id])

end

end


볼드체로된 부분 처럼 항상 DB 쿼리를 하지 않도록, 인스턴스 변수를 활용해서 캐싱하는 형태로 사용하면 항상 DB자원을 사용하는 것을 줄여줄 수 있다.

No2. Dynamic find by methods

find 메소드의 형태를 좀더 간소하게 사용할 수 있는 find_by_methods 의 사용에 대해서 알아보자. 간단하므로 아래 예제로 확인해볼 수 있다.

find 메소드의 컨디션에 해당하는 컬럼을 메소드 명으로 줄 수 있다.

class TasksController < ApplicationController

def incomplete

@tasks = Task.find(:all, :conditions => ['complete =?', false])

@tasks = Task.find_all_by_complete(false)

end

def last_incomplete

@task = Task.find(:first, :conditions => ['complete = ?', false], :order => 'created_at DESC')

@task = Task.find_by_complete(false, :order => 'created_at DESC')

end

end

No3. Find through association

모델간의 관계를 이용해서 데이타를 찾아도록 하는 방법

모델의 관계는 다음과 같다.

class Project < ActiveRecord::Base

has_many :tasks

end

class Task < ActiveRecord::Base

belongs_to :project

end

이경우 Association 을 이용해서 데이타를 가져오면서  No2 에서 제공하는 find_by_methods 까지 활용해보자.

class ProjectsController < ApplicationController

def show

@project = Project.find(params[:id])

@tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false])

@tasks = @project.tasks.find_all_by_complete(false)

end

end

깔끔한 코드 ~~

No4. Move find into model

custom find 메소드를 생성해서 find 메소드를 모델로 이동시킬 경우 얻을 수 있는 장점

class TaskController < ApplicationController

def index

@tasks = Task.find_all_by_complete(false, :order => 'created_at DESC')

@tasks = Task.find_incomplete

end

end

위와 같은 형태에서 find_all_by_complete 를 find_incomplete 라는 클래스 메소드로 활용하게 되면 Task 모델에 다음과 같은 클래스 메소드를 추가하면 된다.

def self.find_incomplete

find_all_by_complete(false, :order => 'created_at DESC')

end

이런식으로 모델의 클래스 메소드로 생성해 두는 경우 아래와 같이 컨트롤러에서도 활용 가능하다.

class ProjectController < ApplicationController

def show

@project = Project.find(params[:id])

@tasks = @project.tasks.find_all_by_complete(false, :order => 'created_at DESC')

@tasks = @project.taskts.find_incomplete

end

end

No5. Using with scope

find 메소드를 커스텀하게 작성해서 모델로 이동시켜서 사용하는 경우, 커스텀 find 메소드로는 파라미터를 어떻게 전달할까?

class Task < ActiveRecord::Base

belongs_to :project

def self.find_incomplete

find_all_by_complete(false, :order => 'created_at DESC')

end

end

이렇게 커스텀 find 메소드인 find_incomplete 를 생성했다. 이 메소드를 사용하는 컨트롤러에서는 호출시에 현재로서는 파라미터를 전달할 방법이 없다.

예를 들어서 아래와 같이 호출하고 싶은 경우 find_incomplete 메소드를 어떻게 수정하면 될까?

class TaskController < AppliationController

def index

@tasks = Task.find_incomplete :limit => 20  #이렇게 파라미터를 추가해서 호출하고 싶다.

end

end

방법은 Rails 에서 제공하는 함수인 with_scope 를 사용하면 좀더 우아하게 처리할 수 있다.

find_incomplete 클래스 메소드를 수정해보자.

def self.find_incomplete(options = {})

with_scope :find => options do

find_all_by_complete(false, :order => 'created_at DESC')

end

end

이렇게 수정하면 어떠한 형태의 파라미터도 다이내믹하게 처리할 수 있겠다.

우아해졌다 ~~

Tags

History

Last edited on 03/28/2007 17:56 by JasonPA

Comments (0)

You must log in to leave a comment. Please sign in.