'재미' 카테고리의 다른 글
슬러거의 진화 (0) | 2007.12.31 |
---|---|
스프링노트 UI 개선 릴리즈 (4) | 2007.07.09 |
오픈마루 첫번째 데브데이 - RubyTutorialSession 자료 및 후기 (1) | 2007.07.03 |
루비세미나3회후기 (0) | 2007.06.19 |
Railscasts (no1 ~ no5) : 레일즈 스크린캐스트 (0) | 2007.03.28 |
슬러거의 진화 (0) | 2007.12.31 |
---|---|
스프링노트 UI 개선 릴리즈 (4) | 2007.07.09 |
오픈마루 첫번째 데브데이 - RubyTutorialSession 자료 및 후기 (1) | 2007.07.03 |
루비세미나3회후기 (0) | 2007.06.19 |
Railscasts (no1 ~ no5) : 레일즈 스크린캐스트 (0) | 2007.03.28 |
튜토리얼1 - [멘토:강문식, 유지만] Ruby반 - 세미나룸#4
- 최종참가자: 10명 - 날개, 김성안, 브루펜시럽, 우주, 트위니, Celeste, Dano, iron, Raven, 이두원
링크
문서
소스
목표 :
ActiveRecord 를 사용하지 않고 ActiveRecord 의 REST 버젼이라고 할 수 있는 ActiveResource 만을 사용해서 스프링노트의 페이지를 다룰 수 있는 게시판을 만들어 본다.
Edge Rails 란 레일스 최신 개발소스를 의미함.
(참고) vendor/rails 디렉토리에 최신의 레일스 소스를 내려받으면 Edge 로 개발하는 환경이 갖추어 진다.
vendor/rails/railties/lib/initializer.rb 에 아래와 같은 메소드가 존재.
def framework_root_path
defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails"
end
인증키 받기 : 도움말 참조
config/springnote.yml 파일 생성후 아래와 같은 정보 추가.
springnote:
open_id: 자신의오픈아이디
user_key: 인증센타를통해받은유저키
app_key: 인증센타를통해받은어플리케이션키
ActiveRecord 를 사용하지 않도록 설정
필수 세션 정의 필요
스프링노트 API 인증에 필요한 설정 파일 내용 로딩 (springnote.yml)
(참고 : 개발환경에서 상세하게 에러메시지를 남기도록 설정) : config/environmants/development.rb 파일내용중 아래와 같이 수정
lib/initializer.rb 작성
config/environment.rb 파일에 monkey_patch 한 라이브러리 파일 로딩하도록 수정
app/conteollers/page_controller.rb 에서 update 부분을 수정하면 됨.
# ActiveResource 에는 update_attributes 가 구현이 안되어있다. 때문에 아래와 같이 수정하고 명시적으로 save 를 호출해주면 됨.
def update
@page = Page.find(params[:id])
respond_to do |format|
params[:page][:identifier] = params[:id]
if @page.attributes = params[:page]
@page.save
flash[:notice] = 'Page was successfully updated.'
format.html { redirect_to(@page) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @page.errors, :status => :unprocessable_entity }
end
end
end
개발환경 레일스 콘솔 실행 : script/console
콘솔상에서 아래와 같이 한줄씩 입력해보고 나오는 결과를 참고해보자.
200 - 399:: Valid response, no exception
404:: ActiveResource::ResourceNotFound
409:: ActiveResource::ResourceConflict
422:: ActiveResource::ResourceInvalid (rescued by save as validation errors)
401 - 499:: ActiveResource::ClientError
500 - 599:: ActiveResource::ServerError
HTTP Verb | REST-URL | Action | URL without REST |
---|---|---|---|
GET | /projects/1 | show | GET /projects/show/1 |
DELETE | /projects/1 | destroy | GET /projects/destroy/1 |
PUT | /projects/1 | update | POST /projects/update/1 |
POST | /projects | create | POST /projects/create |
Path Method | HTTP Verb | Path | Requested Action |
---|---|---|---|
projects_path | GET | /projects | index |
projects_path(1) | GET | /projects/1 | show |
new_project_path | GET | /projects/new | new |
edit_project_path | GET | /projects/1;edit | edit |
projects_path | POST | /projects | create |
projects_path(1) | PUT | /projects/1 | update |
projects_path(1) | DELETE | /projects/1 | destroy |
config/routes.rb :
map.resources :projects
Route | Generated Helper |
---|---|
projects | projects_url, projects_path |
project | project_url(id), project_path(id) |
new_project | new_project_url, new_project_path |
edit_project | edit_project_url(id), edit_ |
이 글은 스프링노트에서 작성되었습니다.
스프링노트 UI 개선 릴리즈 (4) | 2007.07.09 |
---|---|
웹 얼굴 분석 ~~ (1) | 2007.07.05 |
루비세미나3회후기 (0) | 2007.06.19 |
Railscasts (no1 ~ no5) : 레일즈 스크린캐스트 (0) | 2007.03.28 |
Web-based IDE and debugger for Rails (0) | 2007.02.14 |
6월 16일날 세번째 루비 커뮤니티 세미나가 있었다. (잘정리된 deepblue 님의 블로그) 어랏? 그러고 보니 동생 생일날이네.
이번 세미나의 여파로 미투에 친구도 여럿 생겼다 ^^;; 언제나 커뮤니티를 위해 열심히 하는 deepblue 님이 아니었으면, 이번 5개월 만의 모임이 열리기도 힘들었을 것 같고, 오프라인 모임이 자취를 감추었을 수도 있었는데 어쨌든 다행이다.
워낙 급 제안이 되어서 사람들이 많이 올까 했었는데, 다행이도 많은 분들이 오셨다. 그날 가장 먼저 코디안님이 오셨는데, 역시나 바쁘신 분 답게 앉자마자 노트북을 꺼내놓으시고 마구 뭔가를 작성하신다... (이것이 그날 발표자료 였나? ^^). 부산에서 올라오신 분도 있었는데, 이 대목에서는 약간 미안한 마음마져 들었다. 너무나도 가볍게 마음가짐을 갖고 참석을 한터라서, 시간을 빼앗는건 아닌가? 라고잠시 반성..
갑자기 모이긴 했어도 역시나 많은 준비가 필요 없을 정도로 평소에 갖고 있는 내공들을 유감없이 뿜어내는 모습을 보니, 좀 더 자주 만나지 않으면 3시간은 턱없이 부족한 시간이라는 느낌을 받았다. 얘기하고 싶은 분들이 많았는데, 공지기간이 워날 짧아서, 발표주제를 수집할 수가 없어서, 참석하신 분들에게 기회가 다 돌아가지 못한 것 같았다.
언제나 즐거움과 도움과 지식과 노하우를 전달해주는 분들이 모인 자리라 그런지 유쾌한 느낌이었다. 개인적으로는 지난달에 있었던 루비온레일스실전워크샵 에서 발표했던 자료를 간단하게 소개하는 시간을 가졌는데, 짧게 줄여서 내용은 간략하게 하고 루비 커뮤니티에 참여하신 분들의 고마움을 느끼고 있다는 것을 전달하려고 노력은 했는데, 좀 횡설수설 했던 것 같다. (목도 너무 않좋구. 선생님들은 정말 대단하셔 ㅡㅡ;;)
커뮤니티 사람들이 좀더 원활하게 온라인에서 의사소통을 할 수 있는 공간이 어서 정착되면 좋겠다는 생각이 들었다. (그동안 nohmad님이 계속 개인적으로 운영을 해주시고 계셨는데, 이제는 사람도 점점 많아지고 있으니, 좀더 여러 사람이 운영을 도와줄 수 있는 형태로 되었으면 좋겠다 - 좋은 소식이 조만간 있지 않을까 ^^)
어쨌든 사진도 없고 무료한 후기인데, 루비 커뮤니티가 점점 더 활기찬 공간이 되었으면 좋겠다. 다음 세미나가 또 기다려진다.
P.S. 내용중에 이름이 매치가 안돼서 상세히 언급이 안되었으니 ^^;; 양해바랍니다.
이 글은 스프링노트에서 작성되었습니다.
웹 얼굴 분석 ~~ (1) | 2007.07.05 |
---|---|
오픈마루 첫번째 데브데이 - RubyTutorialSession 자료 및 후기 (1) | 2007.07.03 |
Railscasts (no1 ~ no5) : 레일즈 스크린캐스트 (0) | 2007.03.28 |
Web-based IDE and debugger for Rails (0) | 2007.02.14 |
제 2회 루비 세미나 다녀왔습니다. (부제: 루비 코드를 말한다.) (16) | 2007.01.22 |
컨트롤러에서 모델의 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자원을 사용하는 것을 줄여줄 수 있습니다.
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
모델간의 관계를 이용해서 데이타를 찾아도록 하는 방법에 대해서 알아보도록 합시다.
모델의 관계는 다음과 같습니다.
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
깔끔한 코드 ~~
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
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
이렇게 수정하면 어떠한 형태의 파라미터도 다이내믹하게 처리할 수 있겠네요.
우아해졌습니다 ~~
P.S. 보다보니 벌써 동영상이 #11 까지 올라왔네요.. 나머지도 한번 가서 보세요... 짧으니 한꺼번에 보시면 저같은 초보 분들은 도움이 될만한 것들을 금방 얻을 수 있겠습니다.
Declare your scopes within your ActiveRecord::Base subclasses.
class Contact < ActiveRecord::Base이렇게 해주면 아래와 같이 사용하실 수 있습니다.
auto_scope \
:old => {:find => {:conditions => ["born_on < ?", 30.years.ago]}},
:young => {:find => {:conditions => ["born_on > ?", 1.year.ago]}}
end
class Testimonial < ActiveRecord::Base
auto_scope \
:approved => {
:find => {:conditions => ["approved_at < ?", proc {Time.now}]},
:create => {:approved_at => proc {Time.now}}},
:unapproved => {
:find => {:conditions => "approved_at IS NULL"},
:create => {:approved_at => nil}}
end
Testimonial.approved.count
Testimonial.unapproved.create!(params[:testimonial])
@young_contacts = Contact.young
@contacts = Contact.old.find(:all, :conditions => ["name LIKE ?", params[:name]])
오픈마루 첫번째 데브데이 - RubyTutorialSession 자료 및 후기 (1) | 2007.07.03 |
---|---|
루비세미나3회후기 (0) | 2007.06.19 |
Web-based IDE and debugger for Rails (0) | 2007.02.14 |
제 2회 루비 세미나 다녀왔습니다. (부제: 루비 코드를 말한다.) (16) | 2007.01.22 |
행복 + 웃음 + 엘프 + 크리스마스 (바이러스 맞군요) (0) | 2006.12.23 |
이것또한 레일즈 어플리케이션으로 되어있습니다. 스크린캐스트도 올려져 있습니다.
screenshot
설치 방법은 아래와 같습니다.
sudo gem install -y ruby-debug -v 0.6.2
sudo gem install -y coderay
svn checkout http://gyre.bitscribe.net/svn/gyre/trunk gyre
cd gyre
mysqladmin create gyre
rake db:migrate
script/server -p 4000
기본적으로 Rails 1.2.1 로 되어있으니, Rails 1.2.2 를 쓰시는 분들은 config/environment.rb 에서 RAILS_GEM_VERSION 을 변경해 주시면 됩니다.
윈도우즈에 설치하시는 분들은 설치후 재시작시
TypeError in Project#index
Showing app/view/project/index.rhtml where line #32 raised:
can't convert nil into String ....
이런식의 오류가 날 수 있는데요, project_helper.rb 의 render_directory_dialog 에 보면 ENV["HOME"] 정보가 제대로 존재하지 않아서 그렇습니다. 대략 패쓰를 여러분들이 사용하시는 레일즈 어플리케이션이 있는 상위 디렉토리쯤으로 변경하시면 될 것 같습니다.
Gyre 를 설치한뒤 실행시키고 브라우저로 접속하면 처음 화면에서 프로젝트들을 등록하는 화면이 보이게 됩니다. 여기서 기존에 존재하는 레일즈 어플리케이션을 등록하게 되면 Gyre 는 기존의 레일즈 어플리케이션의 application.rb 파일에 내용을 추가하게 됩니다.
### The following was added by Gyre as a horrible, horrible hack.
### Remove if you wish to run the app standalone.
class ApplicationController < ActionController::Base
before_filter :gyre_set_bp_retry
def gyre_set_bp_retry
params["BP-RETRY"] = true
end
end
### EOH (end of horror)
확인해보니 위와 같은 내용이 추가되고 있었습니다. 이러한 것이 추가되는 이유는 익셥션을 핸들링 하기 위해서라는 군요. (브레이크 포인트를 걸기위한 용도로도 사용하는 것 같습니다). 디버거 상에서 어플리케이션이 실행되지 않는 경우에는 행걸릴수도 있으니 주의하라는 당부의 말도 있는 것 보면, 테스트용으로만 잠깐 써보는 것이 전부인 것 같습니다. 아직 많이많이많이 불안불안 합니다.
스크립트 기반의 레일즈 어플리케이션을 이렇게 꼭 브라우저로 IDE를 제공하고 디버깅 할 필요가 있을까 생각이 들기도 했지만, 어쨌든 디버깅에 많은 불편함을 느끼고 있는 저로서는 이러한 디버깅을 할 수 있는 옵션들이 많이 나타나는 것 자체가 반가운 소식입니다. 아직 갈길이 멀게만 느껴지는 중입니다.
루비세미나3회후기 (0) | 2007.06.19 |
---|---|
Railscasts (no1 ~ no5) : 레일즈 스크린캐스트 (0) | 2007.03.28 |
제 2회 루비 세미나 다녀왔습니다. (부제: 루비 코드를 말한다.) (16) | 2007.01.22 |
행복 + 웃음 + 엘프 + 크리스마스 (바이러스 맞군요) (0) | 2006.12.23 |
Douglas Crockford Video: Advanced JavaScript (0) | 2006.12.06 |
Railscasts (no1 ~ no5) : 레일즈 스크린캐스트 (0) | 2007.03.28 |
---|---|
Web-based IDE and debugger for Rails (0) | 2007.02.14 |
행복 + 웃음 + 엘프 + 크리스마스 (바이러스 맞군요) (0) | 2006.12.23 |
Douglas Crockford Video: Advanced JavaScript (0) | 2006.12.06 |
제 1회 루비 세미나 다녀왔습니다. (8) | 2006.11.27 |
Web-based IDE and debugger for Rails (0) | 2007.02.14 |
---|---|
제 2회 루비 세미나 다녀왔습니다. (부제: 루비 코드를 말한다.) (16) | 2007.01.22 |
Douglas Crockford Video: Advanced JavaScript (0) | 2006.12.06 |
제 1회 루비 세미나 다녀왔습니다. (8) | 2006.11.27 |
JavaScript 에서 Prototype 객체를 사용해서 함수를 추가하는 이유? (0) | 2006.09.12 |
제 2회 루비 세미나 다녀왔습니다. (부제: 루비 코드를 말한다.) (16) | 2007.01.22 |
---|---|
행복 + 웃음 + 엘프 + 크리스마스 (바이러스 맞군요) (0) | 2006.12.23 |
제 1회 루비 세미나 다녀왔습니다. (8) | 2006.11.27 |
JavaScript 에서 Prototype 객체를 사용해서 함수를 추가하는 이유? (0) | 2006.09.12 |
JavaScript 로 본 MVC 모델 (0) | 2006.09.12 |
행복 + 웃음 + 엘프 + 크리스마스 (바이러스 맞군요) (0) | 2006.12.23 |
---|---|
Douglas Crockford Video: Advanced JavaScript (0) | 2006.12.06 |
JavaScript 에서 Prototype 객체를 사용해서 함수를 추가하는 이유? (0) | 2006.09.12 |
JavaScript 로 본 MVC 모델 (0) | 2006.09.12 |
나는 자애로운 군주(Benevolent Ruler) ?? (0) | 2005.10.31 |
자바스크립트로된 라이브러리 혹은 프레임웍 들을 살펴보다보면 눈엣 가시처럼 거슬리는 코드들이 보인다. 평소에 보지못한방식이라서 그럴 수도 있고, 워낙 고수들이 만들어놓은 자바스크립트 고유의 장점들을 살려서 작성해놓았기 때문일 수도 있다.
어쨌든 그중에 자바스크립트를 생성할때 네임스페이스를 구현하는 방법 등을 둘째 치더라도 (보면 그냥 이해가 되는 부분이기도 하니까) 왜 이런 라이브러리들은 프로토타입 객체를 통해서 함수들을 선언해 놓을까?
가장 큰 이유는 개인적인 생각에서는 메모리의 문제가 아닐까 한다. 물론 다른 이유도 많겠지만...
메모리의 측면에서 보기위한 예를 들면:
[CODE]function mySample() {
var field1 = "test";
var today = new Date();
this.todayis=function(){
alert("Today is " + this.today);
}
}
[/CODE]위와 같은 함수가 있다고 생각해보자. 이때 todayis 라는 함수는 오늘 날짜를 alert 창으로 찍어서 보여줄 것이다.이런식으로 mySample 함수 생성 메소드 내부에 함수를 추가하는 방식을 사용하는 경우에는 mySample 객체의 인스턴스가생성될때 마다 매번 함수를 새로 만드는 형태가 된다. - 객체를 대량으로 만드는 경우에는 메모리 사용면에 있어서 취약할 수 있다.
이런 고려사항때문에 대부분 Prototype 객체를 사용해서 함수를 연결하는 형태를 취하고 있는 것으로 생각된다.
하지만 Prototype 을 사용하는 경우에 주의해야 하는 사항은 가비지 문제이다.
함수내부에 함수를 추가한 형태의 경우에는 내부적으로 클로저가 만들어진 경우인데 (클로저는 함수 내부에 또 다른 함수를 구현하는 경우에만 동작한다), 이때 생성 메소드에서 DOM 엘리먼트를 다루는 경우에는 함수의 지역 변수로 선언된 내용이 가비지 컬렉터에게 수집되지 않는 문제점이 발생할 수 있다.
쩝... 여러가지고 JavaScript 코드를 사용해서 뷰단에서 멋진 효과및 이벤트 처리를 위해서는 많은 고려해야할 사항이 있는 것 같다.
행복 + 웃음 + 엘프 + 크리스마스 (바이러스 맞군요) (0) | 2006.12.23 |
---|---|
Douglas Crockford Video: Advanced JavaScript (0) | 2006.12.06 |
제 1회 루비 세미나 다녀왔습니다. (8) | 2006.11.27 |
JavaScript 로 본 MVC 모델 (0) | 2006.09.12 |
나는 자애로운 군주(Benevolent Ruler) ?? (0) | 2005.10.31 |