Rails 3에서 ActiveRecord 연결 범위를 어떻게 지정합니까?
Rails 3 프로젝트가 있습니다. Rails 3에서는 Arel과 한 스코프를 재사용하여 다른 스코프를 구축 할 수있는 기능이 제공되었습니다. 관계를 정의 할 때 범위를 사용하는 방법이 있는지 궁금합니다 (예 : "has_many").
권한 열이있는 레코드가 있습니다. 내 권한 열을 고려하여 레코드 (관계를 통해 액세스 한 레코드 포함)를 필터링하는 default_scope를 만들고 싶습니다.
현재 Rails 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의 범위를 상위 계층 (컨트롤러 또는 모델에 직접 액세스하는 다른 모든 것)에 노출하지 않도록 권장하며 이렇게하려면 다음이 필요합니다.
- 범위를 만들고 모델의 메서드를 통해 노출합니다. 이 방법은 컨트롤러에 노출하는 방법입니다.
- 모델을 컨트롤러에 노출하지 않는다면 (따라서 그 위에 일종의 서비스 레이어가 있음) 괜찮습니다. 부패 방지 계층 은 서비스이며 범위 구현 방법에 대해 너무 걱정하지 않고 모델의 범위에 액세스 할 수 있습니다.
연결 확장은 어떻습니까?
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.reflection은 연관을 설명하는 반사 객체를 반환합니다. proxy_association.target은 belongs_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
여러 모델의 범위를 병합하기 위해 병합 방법을 사용할 수 있습니다 . 자세한 내용은이 railscast 에서 병합을 검색하십시오.
사용자의 주문 만 받으려는 경우 관계를 사용하지 않는 이유는 무엇입니까?
컨트롤러의 current_user 메서드에서 현재 사용자에 액세스 할 수 있다고 가정합니다.
@my_orders = current_user.orders
이렇게하면 사용자의 특정 주문 만 표시됩니다. 다음을 사용하여 더 깊은 리소스를 얻기 위해 임의로 중첩 된 조인을 수행 할 수도 있습니다.joins
current_user.orders.joins(:level1 => { :level2 => :level3 }).where('level3s.id' => X)
참고 URL : https://stackoverflow.com/questions/2412340/how-do-you-scope-activerecord-associations-in-rails-3
'Programing' 카테고리의 다른 글
Excel range.Rows 속성은 실제로 어떤 역할을합니까? (0) | 2020.12.09 |
---|---|
Git : 삭제 된 코드 찾기 (0) | 2020.12.09 |
Rails : 하나의 양식에서 다중 제출 버튼 (0) | 2020.12.09 |
(function (window, document, undefined) {…}) (window, document)를 사용하면 어떤 이점이 있습니까? (0) | 2020.12.09 |
Java에서 기존 for 루프 대 Iterator / foreach의 성능 (0) | 2020.12.08 |