Home Rails: Calling or delgate instance method from another model
Reply: 1

Rails: Calling or delgate instance method from another model

Asan
1#
Asan Published in 2016-03-12 15:56:33Z

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>
toddmetheny
2#
toddmetheny Reply to 2016-03-12 17:11:40Z

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.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.298179 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO