2014-10-02 62 views
0

我有性病是这样的:如何将STI类重新分配给模型方法中的变量?

class Post 
end 

class Post::Confirmed < Post 
end 

class Post::Draft < Post 
    def confirm! 
    becomes Post::Confirmed 
    end 
end 

...# somewhere in controller 
# POST /posts/1/confirm 
# POST /posts/1/confirm.json 
def confirm 
    @post = Post::Draft.first 
    @post = @post.confirm! # this is the only way I can reload @post with Post::Confrmed 
end 

是它在某种程度上可能使:

@post.confirm! # I want this @post(Post::Draft) to become Post::Confirmed without reassigning 

还是仅仅也不回报率呢?

在此先感谢!

+2

你确定STI在这种情况下是否合适?不会有简单的状态标志和一些范围更有意义吗? – 2014-10-02 21:21:10

+0

我虽然这样做,但范围有点大,然后在这个例子中:所有的子类作为给定类的命名空间,所以草案有自己的方法和确认的职位 - 他们自己的。 我想我可能是错的。但是,STI看起来仍然很完美。 – IlyaDoroshin 2014-10-02 21:21:46

+0

@ muistooshort想象一下,你有购物车。它在结构上与订单相同:它有物品,总价格等,但每个类的方法都不同。 – IlyaDoroshin 2014-10-02 21:25:19

回答

0

我发现这种模式效果最好,它有一个datetime类型字段,用于记录记录被标记的时间。

例如:

def confirm! 
    self.confirmed_at = DateTime.now 
    self.save! 
end 

那么你可以告诉的东西得到了证实。当您遇到被标记但还没有的情况时(例如将来设置发布日期),此功能尤其方便。

虽然看起来有点烦人没有STI的技巧可用,但STI并不总是合适的工具。一般而言,STI是要区分类似但不同的模型,这些模型具有很多共同点或者在一个共同的环境中使用。它不应该被用来处理单一模型的不同状态。

你想在这种情况下是一个状态机类型模式。

+0

实际上,真的,但状态机宝石是可怕的:政治家太复杂了,并且state_machine没有维护一年.. 所有我想用“邦”的方法,这将改变实例(像所有的爆炸 - 方法)。但如果这是不可能的,我会坚持重新分配变量。对我而言,这种方式更加清晰和强大。谢谢你的回答,虽然) – IlyaDoroshin 2014-10-02 22:18:36

+0

我刚刚发现了另一个宝石,实际上看起来很有希望:aasm – IlyaDoroshin 2014-10-02 22:24:14

+1

状态机型宝石并不总是得到很好的维护的原因是因为你自己实现这种行为是微不足道的。试一试。 – tadman 2014-10-05 19:25:29