2011-03-25 12 views
5

Ben şu yolları:Raylar Yolu birden yolları üzerinde kullanılabilir eylemi işlemek için

resources :users do 
    # List reviews made by user 
    resources :reviews, :only => [ :index ] 
end 

resources :products do 
    # List reviews by product, and provide :product_id for creation 
    resources :reviews, :only => [ :index, :new, :create ] 
end 

# Other actions don't depend on other resources 
resources :reviews, :except => [ :index, :new, :create ] 

Her şey ReviewsController#index hariç sağ görünür:

def index 
    if params[:user_id] 
    @reviews = Review.find_all_by_user_id params[:user_id] 
    else 
    @reviews = Review.find_all_by_product_id params[:product_id] 
    end 
    respond_with @reviews 
end 

için standart bir çözüm var acaba Yukarıdaki sorun ya da bunu yapmak için daha iyi bir yol varsa.

cevap

6

Orada neler var, ama isterseniz iki farklı eylemde kullanabilirsiniz. Bu yaklaşım, daha sonra görünümü daha kolay değiştirmenize izin vermeli ve biraz daha güvenli.

match '/products/:product_id/reviews' => 'reviews#product_index' 
match '/users/:user_id/reviews' => 'reviews#user_index' 

yerine ürünün değerlendirme gösterilmeden da denetleyici kodu biraz daha temiz tutmak ve kullanıcının değerlendirme neden olacaktır /products/10/reviews?user_id=100 gibi tuhaf sorgular daha az duyarlı olacaktır.

def product_index 
    @reviews = Review.find_all_by_product_id params[:product_id] 
    respond_with @reviews 
end 

def user_index 
    @reviews = Review.find_all_by_user_id params[:user_id] 
    respond_with @reviews 
end 

diğer alternatif de farklı denetleyicileri kullanmaktır:

match '/products/:product_id/reviews' => 'product_reviews#index' 
match '/users/:user_id/reviews' => 'user_reviews#index' 
+1

Çok güzel öneri. Sanırım "RESTful eylemleri" zihniyetimden kurtulmalıyım. :) –

+1

Bazen işe yarıyor, diğer zamanlarda işe yaramaz. Tamamen dinlendirici eylemlere sadık kalmak isterseniz, denetleyicinin üzerine yazabilirsiniz, bu nedenle de, bir ProductReviewsController ve huzurlu bir UserReviewsController olabilir. Tabii ki zaten bir çok istisnai ve sadece deyim kullanıyorsunuz, bu yüzden örnekte olduğu gibi, açık url eşleştirmeleri kullanmak sizin için en iyi çözüm olabilir. –

+1

Bazılarının dinlenmeye çok fazla sarıldığını duydum ve bazen ayrılmanız gerektiğine katılıyorum, ama bu böyle bir zamana benzemiyor. Aslında, iki kontrolör yaparak, iki kaynağın dinlenme tarzına giriyorsunuz (sadece indeks eylemi). Bu durumda, bir kontrolörde tutar ve paramize uygun yükler. – DGM

0
def index 
    key = [:user_id, :product_id].find{|k| params[k]} 
    @reviews = Review.where(key => params[key]).first 
    respond_with @reviews 
end 
+0

Neden '.first' Bu sana sadece bir inceleme vereceğim Bu yorumların sahip olması gereken polimorfik çağrışımlar için de geçerli değildir. – Galen

1

Bazı eklentileri böyle declarative_authorization veya cancan olarak sizin için kaynak yüklemek için yollar var, diğerleri vardır eminim.

Gördüğüm diğer çözümler, denetleyicide nesneyi yüklemek için özel bir yöntem yapmak ve bu yöntemde esas olarak burada sahip olduğunuz mantıktır; sadece indeks işleminin kendisinden çıkarır. Yöntem daha sonra bir önceki filtre olarak da çağrılabilir.

mantık yapmanın bir başka yolu (ana nesnesi ile başlamaktır

güzel çok üst nesne gerekirse:?.

 
before_filter :load_collection, :only => :index 

private 
def load_collection 
    if params[:user_id] 
    @user = @parent = User.find(params[:user_id]) 
    else 
    @product = @parent = Product.find(params[:product_id]) 
    end 
    @reviews = @parent.reviews 
end 
İlgili konular