【问题标题】:Removing resource depending on other resource根据其他资源删除资源
【发布时间】:2012-05-07 21:28:26
【问题描述】:

我有用户和项目资源以及连接它们的名为 project_members 的联接表。我希望在所有用户离开项目时具有功能,项目会自行销毁,如下面的规范:

 75     it 'deletes the project when there are no more users on it' do
 76       lambda do
 77         project.users.clear 
 78       end.should change(Project, :count).by(-1)
 79     end

到目前为止,我想出了这条线,但不知道该放在哪里......

@project.destroy if @project.users.empty?

编辑:这是我的模型

用户模型(我正在使用 Devise)

  1 class User < ActiveRecord::Base
  2 
  3   has_many :synapses #aka project_members      
  4   has_many :projects, :through => :synapses
  5 
  6   # Include default devise modules. Others available are:
  7   # :token_authenticatable, :encryptable, :lockable, :timeoutable and :omniauthable
  8   devise :database_authenticatable, :registerable,
  9          :recoverable, :rememberable, :trackable, :validatable,
 10          :confirmable      
 11   
 12   # Setup accessible (or protected) attributes for your model
 13   attr_accessible :email, :password, :password_confirmation, :remember_me
 14 end

项目模型

  1 class Project < ActiveRecord::Base
  2 
  3   has_many :synapses
  4   has_many :users, :through => :synapses, :dependent => :nullify
  5   has_many :tasks, :dependent => :destroy
  6 
  7   #use this when you don't have callbacks
  8   #has_many :tasks, :dependent => :delete_all
  9 
 10   validates :name, :presence => true,
 11             :uniqueness => true
 12   validates :description, :presence => true
 13 
 14   attr_accessible :name, :description
 15 
 16 end

突触模型 AKA(项目成员)

  1 class Synapse < ActiveRecord::Base
  2 
  3   belongs_to  :user,
  4               :class_name => 'User',          
  5               :foreign_key => 'user_id'       
  6   belongs_to  :project,
  7               :class_name => 'Project',       
  8               :foreign_key => 'project_id'    
  9   
 10 end

任务模型

  1 class Task < ActiveRecord::Base
  2 
  3   belongs_to :project
  4   belongs_to :user
  5 
  6   validates :name, :presence => true
  7   validates :description, :presence => true,
  8                           :length => { :minimum => 10 }
  9 
 10   attr_accessible :name, :description
 11 
 12 end

【问题讨论】:

  • 您能否描述一下这三个模型是如何协同工作的?您是使用has_and_belongs_to_many 还是has_many, :through 连接用户和项目?
  • 刚刚添加了它们。我认为他们不是最好的,他们可以改进。欢迎提出任何建议:)

标签: ruby-on-rails


【解决方案1】:

成员模型上的回调应该这样做:

class ProjectMember < ActiveRecord::Base
  after_destroy :remove_project_if_last_member
  private
    def remove_project_if_last_member
      project.destroy if project.users.empty?
    end
end

【讨论】:

  • after_destroy?我不想破坏用户,只想破坏用户和项目之间的链接......当没有链接时,项目应该被破坏。但我认为这是在正确的轨道上,也许是项目模型中的 before_delete 回调?
  • @oFca ProjectMember 课程怎么样?答案已编辑以反映。
  • 也许...将我的模型添加到问题中,这样您就可以准确地看到您正在处理的内容。我也认为他们需要一些工作,所以如果您发现任何建议,请告诉我:)
  • 它不起作用。仍然说项目数量没有改变。也许那是因为这个“项目”是未定义的并且返回零?如果是,如何正确分配?
  • @oFca 我认为project.synapses.destroy_all 会这样做。
【解决方案2】:

首先,您的关系陈述可以简化:

belongs_to  :user,
  :class_name => 'User',          
  :foreign_key => 'user_id'

可以变得简单

belongs_to  :user

:class_name:foreign_key 属性默认为您拥有它们。

如果最后一个用户离开项目,您应该在 Synapses 类上放置一个回调来销毁项目。像这样的:

class Synapse < ActiveRecord::Base

  after_destroy :remove_project_if_last_member

  private

  def remove_project_if_last_member
    project.destroy if project.users.empty?
  end

end

[注意:我从另一个答案中复制了 after_destroy 回调——如果那个已经很好,那么编造一些东西是没有意义的。]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 2011-03-18
    • 2020-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    相关资源
    最近更新 更多