문제

Rails 3 프로젝트가 있습니다. Rails 3과 함께 Arel과 다른 범위를 재사용하여 다른 범위를 구축 할 수있는 능력이 있습니다. 관계를 정의 할 때 스코프를 사용하는 방법이 있는지 궁금합니다 (예 : "has_many").

권한 열이있는 레코드가 있습니다. 권한 열을 고려하여 기본값을 구축하여 (관계를 통해 액세스 한 레코드조차도) 필터링됩니다.

현재 레일 3에서 Default_scope (내가 찾은 패치 포함)는 Proc (후기 가변 바인딩에 필요한)를 통과시키는 실행 가능한 수단을 제공하지 않습니다. 명명 된 스코프를 전달할 수있는 has_many를 정의 할 수 있습니까?

지명 된 범위를 재사용한다는 아이디어는 다음과 같습니다.

Orders.scope :my_orders, lambda{where(:user_id => User.current_user.id)}
has_many :orders, :scope => Orders.my_orders

또는 관계에서 이름이 지정된 스코프를 암시 적으로 코딩하는 것과 같습니다.

has_many :orders, :scope => lambda{where(:user_id => User.current_user.id)}

나는 단순히 늦은 바인딩으로 default_scope를 적용하려고 노력하고 있습니다. Arel 접근 방식을 사용하는 것이 좋습니다 (있는 경우). 그러나 실행 가능한 옵션을 사용합니다.

현재 사용자를 언급하고 있기 때문에 마지막으로 평가되지 않은 조건에 따라 다음과 같이 의존 할 수 없습니다.

has_many :orders, :conditions => ["user_id = ?", User.current_user.id]
도움이 되었습니까?

해결책

나는 당신이 살펴 보는 것이 좋습니다 "이름이 지정된 범위가 죽었다"

저자는 Arel이 얼마나 강력한 지 설명합니다 :)

도움이되기를 바랍니다.

2014 년 3 월 1 일 편집

일부 의견에 따르면, 차이는 이제 개인적인 취향의 문제입니다.

그러나 나는 여전히 개인적으로 Arel의 범위를 상단 계층 (컨트롤러 또는 모델에 직접 액세스하는 다른 것)에 노출하지 않는 것이 좋습니다.

  1. 스코프를 만들고 모델에서 메소드를 통해 노출하십시오. 이 방법은 컨트롤러에 노출되는 방법입니다.
  2. 모델을 컨트롤러에 노출시키지 않으면 (따라서 그 위에 어떤 종류의 서비스 계층이 있습니다) 괜찮습니다. 반부패 층 ~이다 서비스와 스코어가 구현되는 방법에 대해 너무 걱정하지 않고 모델의 범위에 액세스 할 수 있습니다.

다른 팁

연관 확장은 어떻습니까?

class Item < ActiveRecord::Base
  has_many :orders do
    def for_user(user_id)
      where(user_id: user_id)
    end
  end
end

Item.first.orders.for_user(current_user)

업데이트 : 클래스 방법이나 범위와 달리 협회 확장에 대한 이점을 지적하고 싶습니다. 협회 대리의 내부에 액세스 할 수 있다는 것입니다.

proxy_association.owner는 협회가 일부인 객체를 반환합니다. proxy_association. 반사는 연관성을 설명하는 반사 객체를 반환합니다. proxy_association.target은 solgs_to 또는 has_one의 관련 객체를 반환하거나 has_many 또는 has_and_belongs_to_many의 관련 객체 모음을 반환합니다.

자세한 내용은 여기를 참조하십시오. http://guides.rubyonrails.org/association_basics.html#association-extensions

스코프 대신 방금 클래스 메토드를 정의하고 있습니다.

def self.age0 do
  where("blah")
end

나는 다음과 같은 것을 사용합니다.

class Invoice < ActiveRecord::Base
  scope :aged_0,  lambda{ where("created_at IS NULL OR created_at < ?", Date.today + 30.days).joins(:owner) }
end 

당신이 사용할 수있는 병합 다른 모델에서 스코프를 병합하기위한 방법. 자세한 내용은 Merge를 검색하십시오 Railscast

사용자의 주문을 받으려고한다면 관계를 사용하지 않는 이유는 무엇입니까?

현재 사용자가 컨트롤러의 current_user 메소드에서 액세스 할 수 있다고 가정합니다.

@my_orders = current_user.orders

이를 통해 사용자의 특정 주문 만 표시됩니다. 또한 임의로 중첩 된 조인을 수행하여 사용하여 더 깊은 리소스를 얻을 수 있습니다. joins

current_user.orders.joins(:level1 => { :level2 => :level3 }).where('level3s.id' => X)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top