ame*_*ini 13 ruby-on-rails polymorphic-associations ruby-on-rails-4 rails-activerecord
鉴于路线:
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
Run Code Online (Sandbox Code Playgroud)
而型号:
class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true
end
Run Code Online (Sandbox Code Playgroud)
当我编辑或添加评论时,我需要回到"可评论"对象.但是我有以下问题:
1)redirect_to在comments_controller.rb根据父对象上的将是不同
2)关于观点的参考文献也会有所不同
= simple_form_for comment do |form|
Run Code Online (Sandbox Code Playgroud)
是否有实用的方法来共享此comment资源的视图和控制器?
chr*_*ris 18
在Rails 4中,您可以将选项传递给关注点.所以,如果你这样做:
# routes.rb
concern :commentable do |options|
resources :comments, options
end
resources :articles do
concerns :commentable, commentable_type: 'Article'
end
Run Code Online (Sandbox Code Playgroud)
那么当你rake routes,你会看到你得到一条路线
POST /articles/:id/comments, {commentable_type: 'Article'}
这将覆盖请求尝试设置以保证其安全的任何内容.然后在你的CommentsController中:
# 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
Run Code Online (Sandbox Code Playgroud)
使用rspec测试这种控制器的一种方法是:
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
Run Code Online (Sandbox Code Playgroud)
Arj*_*jan 12
您可以在之前的过滤器中找到父类,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
现在,您可以根据父类型重定向或执行任何操作.
例如在视图中:
= simple_form_for [@parent, comment] do |form|
Run Code Online (Sandbox Code Playgroud)
或者在控制器中
comments_controller.rb
redirect_to @parent # redirect to the show page of the commentable.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2840 次 |
| 最近记录: |