基于嵌套资源属性更改资源属性的方法

时间:2014-04-28 22:23:52

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

我有一个Rails 4应用程序。相当简单的问题;我写了一个方法,但我不知道它应该去哪里以及如何调用它。

我有一个资源Goals和一个嵌套资源Tasks(即每个目标都有任务)。所有这一部分都可以正常工作。

我想要做的是设置它,以便status的每个task的{​​{1}}为真,goal的{​​{1}}变为真。

我想使用的方法的内容是:

status

检查所有goal个任务是否都有completed = true @goal.tasks.each do |t| if !t.status? completed = false end end if completed? @goal.status = true end :true,如果是,则将goal的{​​{1}}更改为true。

我的想法是将该方法放在status模型中,但这是我能猜到的。

  • 方法在哪里? (它是否像我想的那样在模型中?)
  • 我如何(/我是否需要)调用该方法?

(我知道这个方法可能会有一些小的语法错误,但一旦我真的可以使用它,我就能测试并调整它!)

感谢任何人花时间看一看。

1 个答案:

答案 0 :(得分:1)

您可以按照以下方式简化功能:

@goal.status = @goals.tasks.map(&:complete).all?

假设您想尽快知道goal是否完整,您需要将此功能放入Task模型中。你可以这样做:

def Task < ActiveRecord::Base
  belongs_to :goal

  after_save :goal_completed

  def goal_completed
    if self.goal.tasks.map(&:completed).all?
      self.goal.update_attribute(:completed, true)
    end
  end
end

正如您所看到的,如果一个tasks有很多goal,这可能会很快变得昂贵,因为您正在提取所有goal个{ {1}}每次保存tasks。因此,对于更大的数据库,我建议为每个目标保留已完成任务的计数。 (这实际上与我在我的项目中实现的内容非常类似。)

首先,您需要在task goals中添加一个计数器缓存列(如果您还没有),并将另一列添加到名为tasks_count的{​​{1}} {1}},或类似的东西。确保它们都默认为零。

goals

希望这会有所帮助。快乐的编码!