我与投票,评论和帖子有多态关联,如下所示:
class Vote < ActiveRecord::Base
belongs_to :voteable, polymorphic: true
end
class Post < ActiveRecord::Base
has_many :votes, as: :voteable
end
class Comment < ActiveRecord::Base
has_many :votes, as: :voteable
end
当我点击upvote链接时,我会在参数中发送voteable_type
和voteable_id
。在投票控制器中,我想使用这两个字符串找到可投票对象,但我发现的唯一解决方案是eval。我认为从参数中评估字符串并不是一个好主意。
class VotesController < ApplicationController
def find_voteable
@voteable = eval("#{params[:vote][:voteable_type]}.find(params[:vote][:voteable_id])")
end
end
有关如何按类名和ID查找ActiveRecord对象的任何建议?或者,是否有一种更好的方法可以做到这一点,而不是在参数中发送东西?
答案 0 :(得分:6)
您可能想要使用
params[:vote][:voteable_type].classify.constantize.find(params[:vote][:voteable_id])
或
Object.const_get(params[:vote][:voteable_type]).find(params[:vote][:voteable_id])
同时检查
答案 1 :(得分:6)
这不是您的问题的直接答案,但我想挑战您的设计并提出一种不同的方法:我会向两个控制器添加两个独立的vote
方法(posts_controller
和{{ 1}}),类似于:
comments_controller
我认为这更容易阅读和理解。此外,它允许简单和清晰的restful URL。在# in posts_controller.rb
def vote
Post.find(params[:id]).vote
end
routes.rb
另外,它为您提供了resources :posts do
post 'vote', on: :member
end
之类的路径助手,可以构建像vote_post_path(@post)
这样的可读URL。
答案 2 :(得分:2)
const_get
会为你工作吗?
if const_defined? params[:vote][:voteable_type]
votable = const_get params[:vote][:voteable_type]
votable.find params[:vote][:voteable_id]
end