对于嵌套属性

时间:2016-07-28 16:24:13

标签: ruby-on-rails ruby nested-attributes

我有3个模型UserFeatureUserFeature

class User < ActiveRecord::Base
  has_many :user_features
  has_many :features, through: :user_features
end


class Feature < ActiveRecord::Base
  has_many :user_features
  has_many :users, through: :user_features
end


class UserFeature < ActiveRecord::Base
  belongs_to :user
  belongs_to :feature
end

我已经在数据库中创建了许多功能,并在创建具有以下代码的用户时与用户相关联的功能

<%= form_for @user do |f| %>
  // some user_fields
  <% Feature.all.each do |feature| %>
     <%= check_box "user[feature_ids][], feature.id %>
  <% end %>
  // submit button here
<% end %>

在我UserController我的代码

class UserController < ApplicationController
  def create
    @user = User.new(permit_params)
    @user.save
  end

  def update
    @user = User.find(params[:id])
    @user.update_attributes(permit_params)
  end 

  private
    def permit_params
      params.require(:user).permit(:name, :email, user_feature_ids: [])
    end
end

当我提交时,它会创建并更新用户,并在UserFeature表格中输入我已检查过的功能。

如果我取消选中任何功能,当更新用户时,它将删除UserFeature

中的相对记录

这里没有任何问题,一切都按预期进行。

但是现在我想在删除user_feature时执行一些活动。

为此,我在UserFeature after_destroy :some_activity

中写了一个回调函数
class UserFeature < ActiveRecord::Base
  belongs_to :user
  belongs_to :feature

  after_destroy :some_activity

  def some_activity
     // some code
  end
end

但它没有用,当我检查为什么它在删除user_feature时没有调用destroy调用时,我发现它将调用SQL查询而不是在未经检查的user_feature上调用destroy

这就是afterbefore destroy回调无效的原因。

任何人都可以告诉我,如何在删除UserFeature时执行任何活动?

1 个答案:

答案 0 :(得分:0)

after_destroy之后不会触发delete回调,因为这是delete的实现方式。引自docs

  

Active Record对象未实例化,因此不会执行对象的回调,包括任何:依赖关联选项。 [...]注意:虽然它通常比替代方法#destroy快得多,但跳过回调可能会绕过应用程序中的业务逻辑,从而确保参照完整性或执行其他重要工作。

而不是关联类上的after_destroy回调,您可以对关联定义使用after_remove回调,如Rails Guide about Association Callbacks中所述。