2013-07-27 2 views
0

나는 팀 트리 하우스 코스를 팔고있다. 다시 고려되는 사항 중 하나는 게시 된 상태의 user_id를 현재 로그인 한 사용자의 user_id로 제한하는 기능입니다. 이미 게시하기 위해 로그인해야하는 필터를 이미 설정 했으므로 여기에서하려는 것은 사용자가 다른 사용자로 상태를 게시하지 못하게하는 것입니다.has_many 관계는 new와 어떻게 작동합니까?

사용자는 has_many :statuses

이 무엇에서 상태 #이 방법을 생성하는 컨트롤러의 모양이다

def create 
    @status = Status.new(params[:status]) 

    respond_to do |format| 
     if @status.save 
     format.html { redirect_to @status, notice: 'Status was successfully created.' } 
     format.json { render json: @status, status: :created, location: @status } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @status.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

우리가 변화하고있는 것은 우리가 고안를 사용하는 지금 @status = Status.new(params[:status])

입니다 사용자 모델이므로 현재 사용자는로 표시됩니다. current_user

다음 변경 사항은 cr입니다. 어갈 : @status = current_user.statuses.new(params[:status])

이 문 내가 여기에 무슨 일이 있었는지 알아 내기 위해 노력

내에서 지옥을 혼란.

다음

은 레일 콘솔 프로세스의 내 탐사입니다 :

irb(main):003:0> User.first.statuses 
    User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1 
    Status Load (0.1ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."user_id" = 2 
=> [#<Status id: 2, content: "this is a test status", created_at: "2013-07-23 20:53:35", updated_at: "2013-07-23 20:53:35", user_id: 2>, #<Status id: 3, content: "test2", created_at: "2013-07-23 21:34:59", updated_at: "2013-07-23 21:34:59", user_id: 2>] 
irb(main):004:0> User.first.statuses.class 
    User Load (0.6ms) SELECT "users".* FROM "users" LIMIT 1 
    Status Load (0.3ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."user_id" = 2 
=> Array 
irb(main):005:0> User.first.statuses.new.class 
    User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1 
=> Status(id: integer, content: text, created_at: datetime, updated_at: datetime, user_id: integer) 
irb(main):006:0> Array.new 
=> [] 
irb(main):007:0> Array.new.class 
=> Array 
irb(main):008:0> 

왜 User.first.statuses 배열이었다에서 개체의 클래스가 (예상대로) 반환 발견 때 배열에서 호출되는 .new 클래스는 새로운 Status를 생성했습니다. 어떻게/왜이게 효과가 있니? Array.new를 호출하면 배열을 얻습니다. 배열 객체에서 new를 호출하지 않습니까?

+0

Array.superclass 대 User.first.statuses.superclass –

+0

Oh!을 확인하십시오. Array의 수퍼 클래스는 object이고 User.first.statuses에서 반환 한 배열의 수퍼 클래스는 ActiveRecord :: Base입니다. 어떻게 그랬습니까? ActiveRecord :: Base로부터 상속받은 별도의 배열 클래스를 만들었습니까? – Senjai

+0

http://stackoverflow.com/questions/1529606/how-do-rails-association-methods-work 잘 설명합니다. –

답변

2

트릭이 current_user.statuses이면 배열을 반환하지 않습니다. 물론 그것은 배열처럼 보입니다. 심지어 current_user.statuses.class을 시도해 보면 어레이라고 말할 것입니다. 그러나 그것이 지연 평가 된 후에입니다. 은 실제로이며, ActiveRecord::Relation 개체이며, 레일 콘솔에 current_user.statuses.foo을 시도하여 직접 확인할 수 있습니다. undefined method 'foo' for #<ActiveRecord::Relation:0x007fba7d603918>과 같은 메시지가 표시됩니다. ActiveRecord :: Relation은 ActiveRecord의 유용한 부분 중 하나입니다.이 기능은 ActiveRecord :: Relation이 아닌 다른 항목을 요청할 때까지 개체를 체인으로 연결하는 동안 범위를 관리하고 데이터베이스에 대해 실제로 쿼리를 수행하지 않습니다.

Ryan Bates는 자신의 Railscast에서이 점을 잘 설명하고 있으며,이 점에 대해서도 설명한 블로그 ActiveRecord::Relation vs. Arel에 대해 설명합니다.