我有点像ruby on rails的新手,并从samurails.com single table inheritance with rails 4 tutorial开始添加不同的评论类型。这很有效,但我遇到的问题是当我尝试使用多态关联来获取注释和特定类型以在其他模型(如项目和挑战)下运行时。常规评论有效,但具体类型不适用。
我没有看到任何明确说明如何进行此项工作或其他任何选择,所以任何帮助将不胜感激。
class Comment < ActiveRecord::Base
has_merit
acts_as_votable
belongs_to :commentable, :polymorphic => true
belongs_to :user
belongs_to :commenttype
belongs_to :project
def self.types
%w(Question Idea Problem)
end
def commentable_type=(sType)
super(sType.to_s.classify.constantize.base_class.to_s)
end
scope :questions, -> {where(type: 'Question')}
scope :ideas, -> {where(type: 'Idea')}
scope :problems, -> {where(type: 'Problem')}
end
class Question < Comment
end
class Idea < Comment
end
class Problem < Comment
end
class Project < ActiveRecord::Base
belongs_to :user
has_many :comments, :as => :commentable, :class_name => "Comment"
has_many :questions, :as => :commentable, :class_name => "Question"
has_many :ideas, :as => :commentable, :class_name => "Idea"
has_many :problems, :as => :commentable, :class_name => "Problem"
delegate :questions, :ideas, :problems, to: :comments
end
class CommentsController < ApplicationController
before_action :set_commentable, only: [:index, :new, :create]
before_action :set_type
before_action :set_comment, only: [:show, :edit, :update, :destroy]
def index
@comments = type_class.all
end
def show
end
def new
@comment = type_class.new
end
def edit
end
def create
@comment = @commentable.comments.new(comment_params)
@comment.user = current_user
if @comment.save
redirect_to :back, notice: "#{type} was successfully added."
else
render action: 'new'
end
end
def update
if @comment.update(comment_params)
redirect_to @comment.commentable, notice: "#{type} was successfully updated."
else
render action: 'edit'
end
end
def destroy
@user = current_user
@comment = @commentable.comments.where(comment_user: current_user).first
@commentable.comment.destroy
respond_to do |format|
format.html { redirect_to @commentable, notice: "Comment was deleted." }
format.js
end
end
private
def set_comment
@comment = type_class.find(params[:id])
end
def set_type
@type = type
end
def type
Comment.types.include?(params[:type]) ? params[:type] : "Comment"
end
def type_class
type.constantize
end
def set_commentable
@commentable = find_commentable
end
# add more commentable models here
def find_commentable
if params[:challenge_id]
Challenge.find(params[:challenge_id])
else
end
end
def find_commentable
if params[:project_id]
Project.find(params[:project_id])
else
end
end
def comment_params
params.require(type.underscore.to_sym).permit(:body, :type, :user_id, :commentable_id, :commentable_type, :commentable, :comment_type)
end
end
module CommentsHelper
def sti_comment_path(type = "comment", comment = nil, action = nil)
send "#{format_sti(action, type, comment)}_path", comment
end
def format_sti(action, type, comment)
action || comment ? "#{format_action(action)}#{type.underscore}" : "#{type.underscore.pluralize}"
end
def format_action(action)
action ? "#{action}_" : ""
end
end
<%= form_for [commentable, Comment.new], :html => { :multipart => true } do |f| %>
<%= f.text_area :body, class: "form-control", placeholder: "What's on your mind?" %>
<%= f.label :type %><br>
<%= f.select :type, Comment.types.map {|r| [r.humanize, r.camelcase]}, {}, disabled: @type != "Comment" %>
<%= f.submit "Post", class: "btn pull-right" %>