处理固定链接用户更新时已经采用永久链接Rails 3.2

时间:2012-11-10 15:51:46

标签: ruby-on-rails ruby-on-rails-3.2 permalinks

我想了解如何处理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

如果我没有太多意义,请道歉。

提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以尝试使用after_rollback回调处理此问题。

 after_rollback :restore_permalink

 def restore_permalink
   self.permalink = permalink_was if permalink_changed?
 end

这是它的工作原理:Rails中的每个更新/销毁都包含在一个事务中。如果保存失败,则事务回滚并触发回调。 如果自记录加载后更改了旧值(permalink_was),则回调然后将恢复。

有关详细信息,请参阅ActiveModel::DirtyActiveRecord::Transactions

修改

另一方面,可能是另一种解决方案(未经测试) - 只需像这样定义你的访问者:

 def permalink=( value )
   permalink_will_change! unless @permalink == value
   @permalink = value
 end

这样,如果新值与旧值相同,永久链接将不会标记为脏,因此AR不会尝试更新列。

<强>解释

我不知道它实现的是哪个版本的rails(它是相对较新的),但这里是“脏”的工作方式:

  • 您的“标准”(自动生成)属性设置器基本调用 在设置关联之前#{your_attribute}_will_change! 实例变量(即使您设置的值与以前完全相同)
  • 当您调用save时,ActiveRecords会查找已更改的属性(“脏”),并仅使用这些属性构建SQL UPDATE查询(出于性能原因,主要是)
  • 所以如果你想避免你的永久链接在它没有变化时出现在查询中,我认为你必须覆盖标准的setter - 或者避免大规模分配,只有在permalink已经改变时才设置