Matt Hardman
Matt Hardman

Reputation: 23

How do I run a calculation in my ruby on rails model before the view is rendered?

I have an application where users complete a number of tests. The results of these tests is then stored in the database.

class TestOne < ActiveRecord::Base

  belongs_to :user

  before_save :calculate_total

private 

  def calculate_total
    self.total = self.question_1 + self.question_2
  end
end

I then have a summary page which performs some calculations (in the summary page model) and then these values are displayed on the summary page.

class Summary < ActiveRecord::Base

  def self.amount
    amount = 0
    @users.each do |u|
       if u.test_ones.present?
          amount += 1
       else
       end

       if u.test_twos.present?
       else
       end

       return amount
   end
 end

The problem I am having is that the calculations (amount) do not update when new data is saved. I am assuming there is some code I can put in the model to make it recalculate before the summary view is rendered (similar to the before_save in the other model)?

Thanks in advance x

Upvotes: 1

Views: 192

Answers (1)

whodini9
whodini9

Reputation: 1434

You can use before_action or before_filter (deprecates in Rails 5.1) in your controller (the controller control's presenting the view layer and the model handles the logic of the records. Depending on how complex your action is, this may be a bad solution. If it takes a long time, or the flow gets complex, then it is better to keep this out of the controller. See this post for more info. Also note the render flow in this example:

def update
  if @tree.update(tree_params) # Render / Re-route based on truthy.
    redirect_to(@tree)
  else
    render('edit')
  end
end

However, there are other libraries that specifically handle things like this. For example, ReactJs will automatically re-render components when the 'properties' or 'state' of the component changes. It may be too much overhead to implement React just for this, but if you anticipate having lots of dynamic page data it may be better to use some facet of javascript to automate view layer components.

Upvotes: 1

Related Questions