Calling a method from one class to another - ruby-on-rails

In PilotRaceLap model class I am trying to call a method from another class but keep getting NoMethodError.
class PilotRaceLap < ActiveRecord::Base
acts_as_paranoid
belongs_to :race_session
def mark_splitted
prl = RaceSessionAdapter.track_lap_time(pilot.transponder_token,lap_time/2) <<<ERROR HERE
end
track_lap_time is declared in this adapter class:
class RaceSessionAdapter
attr_accessor :race_session
def track_lap_time(transponder_token,delta_time_in_ms)
...
end
race_session model class starts like that:
class RaceSession < ActiveRecord::Base
acts_as_paranoid
has_many :pilot_race_laps
has_many :race_attendees

track_lap_time should be a class method (it's instance method right now). Just add self. before name.
def self.track_lap_time()
...
end
or write this method in class << self block
class << self
def track_lap_time()
...
end
end

Use RaceSessionAdapter.new.track_lap_time()

Related

How can I call a class method from Model rails

app/services/mail_service
class MailService
def subscribe
code
end
end
User Model
class User < ActiveRecord::Base
after_create :user_subscribe
def user_subscribe
Services::MailService.new
end
end
It shows error like uninitialized constant Services
You dont have to write Services just write :-
MailService.new
Try this
require 'MailService.rb'
class User < ActiveRecord::Base
after_create :user_subscribe
def user_subscribe
MailService.new
end
end

Can I call a class method from another model in Rails?

I'm trying to call a class method (currently a scope) that uses an attribute from its parent (or belongs_to) model, but can't seem to get it working right.
My models:
class Venue < ActiveRecord::Base
attr_accessible :address
has_many :events, :dependent => :destroy
end
class Event < ActiveRecord::Base
belongs_to :venue
scope :is_near, lambda {|city| self(Venue.address).near(city, 20, :units => :km)}
end
I know the syntax is wrong, but I think that illustrates what I'm intending to do. I want to get the address of the venue and call another method on it. I need the scope in the Event class so I can chain other scopes together.
Appreciate any ideas.
Since #address is not a class method but an instance method, you won't be able to do what you want by using a scope.
If you want to get all the events within a 20km range of a venue, create these class methods in Venue instead:
class Venue < ActiveRecord::Base
def self.events_near_city(city)
venues_near_city(city).map(&:events).flatten
end
private
def self.venues_near_city(city)
near(city, 20, :units => :km)
end
end
Then call it by using Venue.events_near_city(session[:city]) since, as you told me in chat, you're storing the city in the session.
As you've defined it above, address is not a class method - it's an instance method. You would have to have an instance of venue (like you do in your view) to call it.
Searching a bit more I found this page that answered the question in another way. This works better for me because it's simpler to call, and I can use it on various relations. In rails how can I delegate to a class method
class Venue < ActiveRecord::Base
attr_accessible :address
def self.is_near(city)
venues_near_city(city).map(&:events).flatten
end
private
def self.venues_near_city(city)
self.near(city, 20, :units => :km)
end
end
class Event < ActiveRecord::Base
belongs_to :venue
class << self
def is_near(*args, &block)
Venue.is_near(*args, &block)
end
end
end
And I call it with event.is_near(session[:city])

How to access a specified table in database through a custom model class, Ruby on Rails?

I have this custom model, with some methods in it:
class GenericModel < ActiveRecord::Base
self.abstract_class = true
def get_settings
.....
end
end
I want to inherit this GenericModel class in my various other Models like below, so that I can have access to those custom methods:
class ProvinceSetting < GenericModel
end
class CitySetting < GenericModel
end
But, how do I write my custom method so that it acts on a specific table in the database depending upon which Model class is calling it ? Any pointers would be welcome
Is this the correct implementation of get_settings in GenericModel, where self would refer to appropriate model name ?
def self.get_settings(user_id)
user_session = SettingsSession.find_by_user_id(user_id)
if !user_session.blank?
if setting_orig = self.find_by_settings_session_id(user_session.id)
setting = setting_orig.dup
end
else
setting = self.first.dup
end
return setting
end
If you want to call the table name used by the subclass, then you're done - it will do that already:
class GenericModel < ActiveRecord::Base
def get_settings
all # this will get all settings for the subclass that calls it
end
end
If you need to use some other table name, make a method in each subclass that defines the tablename, and call that method in the abstract base model:
class ProvinceSetting < GenericModel
def special_table_name
'foo'
end
end
class CitySetting < GenericModel
def special_table_name
'bar'
end
end
class GenericModel < ActiveRecord::Base
def get_settings
... # use 'special_table_name' method in a query
end
end

Inherit active_record in rails

Right now my classes are look like this.
class BalanceName < ActiveRecord
def before_validation
set_blank_attributes_to_nil(#attributes)
end
end
class Balance < ActiveRecord
def before_validation
set_blank_attributes_to_nil(#attributes)
end
end
I want to inherite activer record into one class and than want to inherite that class into other classes like.
I want something like this.
class CommonActiveRecord < ActiveRecord::Base
def before_validation
set_blank_attributes_to_nil(#attributes)
end
end
class BalanceName < CommonActiveRecord
def before_validation
super
end
end
class Balance < CommonActiveRecord
def before_validation
super
end
end
You can do exactly as you have done except you do not need to redefine the before_validation methods in your subclasses (though I guess these may be here prior to being filled with more specific validation).
You will also need to indicate to rails that your CommonActiveRecord class is abstract and therefore is not persisted by adding:
class CommonActiveRecord < ActiveRecord::Base
self.abstract_class = true
end
You can create module (e.g. lib/common_active_record.rb):
module CommonActiveRecord
def before_validation
set_blank_attributes_to_nil(#attributes)
end
end
And then in your model simply include it:
class BalanceName < ActiveRecord::Base
include CommonActiveRecord
end
class Balance < ActiveRecord::Base
include CommonActiveRecord
end

adding class methods to ActiveRecord::Base

I have created an instance method which is also a callback (if that makes sense) which does some stuff thats irrelevant. I would love to be able to just call:
class Model < ActiveRecord::Base
fix_camelcase_columns
end
Instead at the moment I have this:
def after_find
self.class.columns.each do |column|
self.instance_eval("def #{column.name.to_underscore}; self.#{column.name}; end;")
end
end
I would love to abstract this and use it on other classes. Any pointers?
Well, you can open up ActiveRecord::Base and throw a method there:
class ActiveRecord::Base
def self.fix_camelcase_columns
define_method :after_find do
...
end
end
end
For a cleaner way, create a module:
module CamelcaseFixer
def self.included(base)
base.extend(self)
end
def fix_camelcase_columns
define_method :after_find do
...
end
end
end
and then in your model do
class Model < ActiveRecord::Base
include CamelcaseFixer
fix_camelcase_columns
end
Didn't test the code, see if it works.

Resources