0

我在一个名为 的rails 应用程序中有一个关系表edit_privileges,其中User是“编辑器”,而许多其他类是“可编辑的”。假设其中两个类是MessageComment

我的EditPrivilege模型使用以下代码:

belongs_to :editor, :class_name => "User"
belongs_to :editable, :polymorphic => true

而且User,当然

has_many :edit_privileges, :foreign_key => "editor_id"

为了确定用户是否对某个模型具有编辑权限,我无法进行正常查询:

user.edit_privileges.find_by_editable_id(@message.id)

因为如果用户有编辑权限来编辑与 id 相同的评论@message,则查询将返回 true 并从表中返回错误的编辑权限记录。

因此,我尝试执行以下选项:

user.edit_privileges.find(:all, :conditions => ["editable_id = ? AND editable_type ?", @message.id, @message.class.to_s])
user.edit_privileges.where(:editable_id => @message.id, :editable_type => @message.class.to_s)

它非常适合查找正确的记录,但返回一个数组而不是一个对象([]如果没有编辑权限,则返回一个空数组)。如果我试图创建一种方法来破坏编辑权限,这尤其成问题,因为您无法传递.destroy数组。

我认为附加.first到上述两个解决方案会返回第一个对象,nil如果查询结果为空,那么这真的是最好的方法吗?这样做有什么问题吗?(例如,而不是使用基于动态属性的查找器,例如find_by_editabe_id_and_editable_type

4

1 回答 1

3

使用find(:first, ...)而不是find(:all, ...)获取一条记录(注意它可能返回 nil 而 find 会引发 RecordNotFound 异常)。所以对于你的例子:

user.edit_privileges.find(:first, :conditions => { :editable_id => @message.id, :editable_type => @message.class.to_s })

顺便说一句,如果您使用的是更多的边缘导轨版本(3.x),Model.where(...).first那么新语法是:

user.edit_privileges.where(:editable_id => @message.id, :editable_type => @message.class.to_s).first
于 2011-08-15T06:17:13.120 回答