11

Với các tuyến đường:Mối quan tâm về tuyến đường và mô hình đa hình: cách chia sẻ bộ điều khiển và chế độ xem?

Example::Application.routes.draw do 
    concern :commentable do 
    resources :comments 
    end 

    resources :articles, concerns: :commentable 

    resources :forums do 
    resources :forum_topics, concerns: :commentable 
    end 
end 

Và mô hình:

class Comment < ActiveRecord::Base 
    belongs_to :commentable, polymorphic: true 
end 

Khi tôi chỉnh sửa hoặc thêm nhận xét, tôi cần phải quay trở lại với đối tượng "commentable". Tôi có vấn đề sau, mặc dù:

1) redirect_to trong comments_controller.rb sẽ khác nhau tùy thuộc vào đối tượng phụ huynh

2) Các tài liệu tham khảo về các quan điểm sẽ khác nhau cũng

= simple_form_for comment do |form| 

Is có một cách thực tế để chia sẻ quan điểm và bộ điều khiển cho tài nguyên comment này?

Trả lời

10

Bạn có thể tìm ra cha mẹ trong một trước khi lọc như thế này:

comments_controller.rb

before_filter: find_parent 

def find_parent 
    params.each do |name, value| 
    if name =~ /(.+)_id$/ 
     @parent = $1.classify.constantize.find(value) 
    end 
    end 
end 

Bây giờ bạn có thể chuyển hướng hoặc làm bất cứ điều gì bạn vui lòng tùy thuộc vào loại cha mẹ.

Ví dụ trong một cái nhìn:

= simple_form_for [@parent, comment] do |form| 

Hoặc trong một bộ điều khiển

comments_controller.rb

redirect_to @parent # redirect to the show page of the commentable. 
+0

Cảm ơn ý tưởng; Tôi sẽ cung cấp cho nó một mặc dù tôi có thể có nhiều hơn một phụ huynh. Ví dụ tôi sẽ cần 'simple_form_for [forum, forum_topic, comment]'; hoặc 'redirect_to [forum, forum_topic]'. Tôi sẽ chơi với splats và xem nơi nó được tôi. – amencarini

+0

@amencarini Bạn vẫn có thể làm cho Arjan một ưu tiên và chấp nhận câu trả lời của anh ấy! – Wukerplank

16

Trong Rails 4 bạn có thể vượt qua tùy chọn để lo ngại. Vì vậy, nếu bạn làm điều này:

# routes.rb 
concern :commentable do |options| 
    resources :comments, options 
end 


resources :articles do 
    concerns :commentable, commentable_type: 'Article' 
end 

Sau đó, khi bạn rake routes, bạn sẽ thấy bạn có được một tuyến đường như

POST /articles/:id/comments, {commentable_type: 'Article'}

Điều đó sẽ ghi đè lên bất cứ điều gì theo yêu cầu cố gắng thiết lập để giữ cho nó an toàn. Sau đó, trong CommentsController của bạn:

# comments_controller.rb 
class CommentsController < ApplicationController 

    before_filter :set_commentable, only: [:index, :create] 

    def create 
    @comment = Comment.create!(commentable: @commentable) 
    respond_with @comment 
    end 

    private 
    def set_commentable 
    commentable_id = params["#{params[:commentable_type].underscore}_id"] 
    @commentable = params[:commentable_type].constantize.find(commentable_id) 
    end 

end 

Một cách để thử nghiệm một điều khiển như vậy với rspec là:

require 'rails_helper' 

describe CommentsController do 

    let(:article) { create(:article) } 

    [:article].each do |commentable| 

    it "creates comments for #{commentable.to_s.pluralize} " do 
     obj = send(commentable) 
     options = {} 
     options["#{commentable.to_s}_id"] = obj.id 
     options["commentable_type".to_sym] = commentable.to_s.camelize 
     options[:comment] = attributes_for(:comment) 
     post :create, options 
     expect(obj.comments).to eq [Comment.all.last] 
    end 

    end 

end 
+0

cảm ơn câu trả lời của bạn, nó rất hữu ích! Thật không may tôi đã tìm thấy một sai lầm - trong routes.rb bạn phải sử dụng một mối quan tâm bằng cách sử dụng phương pháp 'quan tâm', như thế này: "quan tâm: commentable, commentable_type: 'Article'". –

+0

bạn chính xác, chỉnh sửa. – chris

Các vấn đề liên quan