Вопрос

I was wondering how to access a Models attributes and then run in a rake task using some methods, from what i have read methods have to be declared outside of the task, but gaining access to the model is throwing me

I know that if i put this

namespace :grab do
 task :scores => :environment do
  puts User.all.inspect
 end
end

I would then have all the users printed

Below is what I am trying to achieve

Rake Task

namespace :grab do
 task :scores => :environment do
  points_total
  allocate_points
 end
end

def points_total
 wrong_predictions = [Prediction.home_score - Result.home_score, Prediction.away_score - Result.away_score]
 wrong_predictions = wrong_predictions.reject { |i| i == 0 }.size # returns 0, 1 or 2
  case wrong_predictions
   when 0 then 3
   when 1 then 1
   else 0
  end
end


 def allocate_points
  Prediction.update_attributes!(score: points_total)

 end

So i need access to my Prediction and Result model to perform these methods...

Any help appreciated

Thanks

EDIT

ok so running the task as it is above gives me the following error

 rake aborted!
 undefined method `home_score' for #<Class:0x4b651c0>

also to update here are my models

class Prediction < ActiveRecord::Base
  attr_accessible :away_score, :away_team, :fixture_id, :home_score, :home_team, :score

  has_one :fixture
end

class Result < ActiveRecord::Base
  attr_accessible :away_score, :away_team, :fixture_date, :home_score, :home_team
end
Это было полезно?

Решение

The problem is because of being a rake task but because of the methods themselves.

Both your Prediction and Result models have a home_score method, but they are instance methods and not class methods as you are trying to use them in your points_total and allocate_points methods.

The difference between a class and an instance method is the object in which the method is called:

  • Class method: is called on the Model itself, as in User.new. The new method is called on the User model to generate a new instance of the Model.
  • Instance method: is callen on a specific instance of a model, as in my_user.name = "Terminator". The name method is called on the specific my_user User to change its (and just its) name.

Looking at your code, your methods home_score are thought to be applied on specific instances of predictions and results, as they are instance methods. This is the error that the console is throwing, the methods are not available for the Class (the Model).

Assuming your rake task is trying to update the total points of each Prediction in your database, the code would be:

lib/tasks/grab.rake

namespace :grab do
 task :scores => :environment do
  Prediction.all.each do |prediction|
    score = points_total prediction, prediction.result
    allocate_points prediction, score
  end
 end
end

def points_total prediction, result
 wrong_predictions = [prediction.home_score - result.home_score, prediction.away_score - result.away_score]
 wrong_predictions = wrong_predictions.reject { |i| i == 0 }.size # returns 0, 1 or 2
  case wrong_predictions
   when 0 then 3
   when 1 then 1
   else 0
  end
end

 def allocate_points prediction, score
  prediction.update_attributes!(score: score)
 end

However, that is a kind of 'pseudo-code' because some relation between Prediction and Result models should exist in order to use them as in points_total method. My code is assuming a has_one association, which sould be also reflected in the models; but as I do not know exactly the whole picture for your app I did not want to change this, just focusing on the rake methods.

Hope that helps,

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top