我想了解如何处理to_param
permalinks
基本上就是这样。
:name
被参数化并在数据库中保存为:permalink
:permalink
:permalink
是唯一的将公司的:permalink
更新为已存在的内容时,我遇到了问题。唯一性验证效果很好,但它会将params[:id]
更改为无效的固定链接,而不是重置并使用现有的params[:id]
当我尝试将permalink
编辑为其他内容时,我收到"Name already taken"
的Flash验证错误,因为它认为我正在编辑现有:permalink
(公司)的公司。该网址反映了自permalink
使用companies_controller.rb
@company = Company.find_by_permalink[:id])
中的更改
我想知道处理这个问题的最佳方法吗?
class Companies < ActiveRecord::Base
before_create :set_permalink
before_update :update_permalink
attr_accessible :name, :permalink
validates :name, :permalink, uniqueness: { message: 'already taken' }
def to_param
permalink
end
private
def set_permalink_url
self.permalink = name.parameterize
end
def update_permalink_url
self.permalink = permalink.parameterize
end
end
如果我没有太多意义,请道歉。
提前致谢。
答案 0 :(得分:0)
您可以尝试使用after_rollback
回调处理此问题。
after_rollback :restore_permalink
def restore_permalink
self.permalink = permalink_was if permalink_changed?
end
这是它的工作原理:Rails中的每个更新/销毁都包含在一个事务中。如果保存失败,则事务回滚并触发回调。
如果自记录加载后更改了旧值(permalink_was
),则回调然后将恢复。
有关详细信息,请参阅ActiveModel::Dirty和ActiveRecord::Transactions。
修改强>
另一方面,可能是另一种解决方案(未经测试) - 只需像这样定义你的访问者:
def permalink=( value )
permalink_will_change! unless @permalink == value
@permalink = value
end
这样,如果新值与旧值相同,永久链接将不会标记为脏,因此AR不会尝试更新列。
<强>解释强>
我不知道它实现的是哪个版本的rails(它是相对较新的),但这里是“脏”的工作方式:
#{your_attribute}_will_change!
实例变量(即使您设置的值与以前完全相同)save
时,ActiveRecords会查找已更改的属性(“脏”),并仅使用这些属性构建SQL UPDATE查询(出于性能原因,主要是)permalink
已经改变时才设置1} LI>