在我们的Rails 4应用程序中,有四种模式:
Clone()
以下是相应的迁移:
class User < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :calendars, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
每次class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :email
t.integer :total_calendar_count
t.integer :owned_calendar_count
t.timestamps null: false
end
end
end
class CreateAdministrations < ActiveRecord::Migration
def change
create_table :administrations do |t|
t.references :user, index: true, foreign_key: true
t.references :calendar, index: true, foreign_key: true
t.string :role
t.timestamps null: false
end
end
end
class CreateCalendars < ActiveRecord::Migration
def change
create_table :calendars do |t|
t.string :name
t.timestamps null: false
end
end
end
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.references :calendar, index: true, foreign_key: true
t.date :date
t.time :time
t.string :focus
t.string :format
t.string :blog_title
t.text :long_copy
t.text :short_copy
t.string :link
t.string :hashtag
t.string :media
t.float :promotion
t.string :target
t.integer :approval
t.text :comment
t.timestamps null: false
end
end
end
退出user
,意味着我们calendar
相应的destroy
,我们希望确保发生以下情况:
administration
是否还有其他administrations
。calendar
模型中的has_many :posts, dependent: :destroy
行,但我们认为检查它也不会有害。我们正在考虑通过Calendar
模型中的private
clear_calendar
方法实现此目标,我们将在Calendar
控制器中将其用作after_destroy回调:
Administrations
这有意义吗?
答案 0 :(得分:2)
这是一种非常明智的方法,整个世界都很高兴您没有将此逻辑置于控制器动作中。
有一点需要注意:通过将此逻辑放在Calendar
模型中,您必须将Calendar
和Administration
绑定在一起。也许你觉得在这个时候还不错,但是一个真正的面向对象的程序,而不是询问另一个模型是否存在,而是告诉模型它想要什么而不是如何它想要它完成(例如,如果这种关联不存在,则删除self
。)
我建议将此逻辑放在PORO中 - 也许是一种服务 - 从数据库支持的对象中删除不必要的耦合。也许这看起来像是这样的:
class Calendar < ActiveRecord::Base
...
private
def clear_calendar
ParentDestructionService.new(self)
end
end
class ParentDestructionService
def initialize(parent)
@parent = parent
end
.....logic goes here.....
end
通过这种方式,您不仅可以将如何流程与不应该关注Administration
的类分开,而且您现在可以将其添加到Sidekiq进程,或简单地将其断开。无论哪种方式,您都会变得更加灵活。现在,将来,您将能够通过该服务发送任何父级,并且事情将按预期发挥作用。