Rails: Calling or delgate instance method from another model

I'm not sure if what I'm trying to do is to call or to delegate an instance method from another model

Here are two similar questions: Ruby on Rails: Calling an instance method from another model

In rails how can I delegate to a class method

I have four models associated:

Order has_many :reservations / belongs_to :order_status

OrderStatus has_many :order

Reservation belongs_to :order / belongs_to :reservation_status

ReservationStatus has_many :reservations

What I'm trying to do:

I want to change the reservation_status_id of the reservation when the order status of the order is updated.

Models:

order.rb

class Order < ActiveRecord::Base

  belongs_to :order_status
  has_many :reservations
  after_update :update_reservations

private
  def update_reservations
    if self.order_status_id == 2
      Reservation.update_status_completed
    end  
  end
end

reservation.rb

class Reservation < ActiveRecord::Base
    belongs_to :order
    belongs_to :reservation_status

    def update_status_completed
        self.reservation_status_id = 5
    end 
end

reservation_status.rb

class ReservationStatus < ActiveRecord::Base
    has_many :reservations
end

order_status.rb

class OrderStatus < ActiveRecord::Base
    has_many :orders
end

I want to change to reservation_status_id of the reservation to 5 when the order status of the order is set to 2. But I'm getting an Undefined method error 'update_status_completed'. As I understand rails can't find the update_status_completed that is in the reservation model.

Here's the log:

   (0.0ms)  begin transaction
  Reservation Load (0.0ms)  SELECT "reservations".* FROM "reservations" WHERE "reservations"."order_id" = ?  [["order_id", 85]]
  SQL (1.0ms)  UPDATE "orders" SET "order_status_id" = ?, "updated_at" = ? WHERE "orders"."id" = ?  [["order_status_id", 2], ["updated_at", "2016-03-12 15:24:49.024769"], ["id", 85]]
   (6.0ms)  rollback transaction
NoMethodError: undefined method `update_status_completed' for #<Class:0x2abfbc8>
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/dynamic_matchers.rb:26:in `method_missing'
        from C:/Users/Antonio/Desktop/RegiSportV01/regisports/app/models/order.rb:67:in `update_reservations'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:432:in `block in make_lambda'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:228:in `call'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:228:in `block in halting_and_conditional'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `call'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `block in call'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `each'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `call'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:92:in `__run_callbacks__'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:778:in `_run_update_callbacks'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/callbacks.rb:310:in `_update_record'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/timestamp.rb:70:in `_update_record'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/persistence.rb:504:in `create_or_update'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/callbacks.rb:302:in `block in create_or_update'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:117:in `call'
... 12 levels...
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/transaction.rb:184:in `within_new_transaction'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:220:in `transaction'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:348:in `with_transaction_returning_status'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:286:in `block in save'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:301:in `rollback_active_record_state!'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:285:in `save'
        from (irb):7
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.4/lib/rails/commands/console.rb:110:in `start'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.4/lib/rails/commands/console.rb:9:in `start'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:68:in `console'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
        from C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/railties-4.2.4/lib/rails/commands.rb:17:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'irb(main):008:0>

Answers


do it in a callback function...

inside your model:

after_save :update_order_status

def update_order_status
  if # relevant condition
     # do stuff
  end
end

you're calling a class method but defining it as an instance method. in order to call:

Reservation.update_status

update_status needs to be defined as:

def self.update_status

but when you're calling a class method...you're not going to have access to self, so you won't be able to say

self.status_id # or whatever it was

that is, you won't be able to call this:

Reservation.update_status_completed # calling as class method

in one model and do this in another:

self.reservation_status_id = 5 # inside that class method trying to use instance 

because you don't have an instance there to get the status_id from. To fix this, pass the value through an argument to the class method so you're not trying to rely on an object you don't have access to.

EDIT: Can't tell exactly which reservation you're trying to update but to update all of them:

# order.rb
def update_reservations_status
  if self.order_status_id == 2
    self.reservations.each do |reservation|
      reservation.update_status_completed
    end
  end     
end

# reservation.rb
def update_status_completed
   self.reservation_status_id = 5
   self.save
end

Now the self in update status completed is referring to an instance...bc we're calling last in update_reservations_status.


Need Your Help

FATAL EXCEPTION: main java.lang.VerifyError: net.sourceforge.jtds.jdbc.TdsCore

java android sql-server jtds

In my Android project I'm using jtds.jdbc for connecting to SQL Server database. While trying to connect I wrote wrong connection string which threw an error saying: "Network error IOException: