Rails:从另一个模型调用或委托实例方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rails:从另一个模型调用或委托实例方法相关的知识,希望对你有一定的参考价值。

我不确定我要执行的操作是从另一个模型中调用还是委托实例方法

这里有两个类似的问题:Ruby on Rails: Calling an instance method from another model

In rails how can I delegate to a class method

我有四个关联的模型:

Order has_many:reservations /属于to:order_status

OrderStatus has_many:order

预订归属地:order /归属地:reservation_status

ReservationStatus has_many:reservations

我正在尝试做的事情:

[我想在更新订单的订单状态时更改预订的reserve_status_id。

型号:

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

我将订单的订单状态设置为2时,将保留的Reservation_status_id更改为5。但是我收到了未定义的方法错误'update_status_completed'。据我了解,Rails找不到预订模型中的update_status_completed。

这里是日志:

   (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>
答案

在回调函数中执行...

在模型内:

after_save :update_order_status

def update_order_status
  if # relevant condition
     # do stuff
  end
end

您正在调用类方法,但将其定义为实例方法。为了打电话:

Reservation.update_status

update_status需要定义为:

def self.update_status

但是当您调用类方法时...您将无法访问self,因此您将无法说出

self.status_id # or whatever it was

即,您将无法拨打此电话:

Reservation.update_status_completed # calling as class method

在一种模型中,在另一种模型中:

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

因为您那里没有实例来获取status_id。要解决此问题,请将值通过参数传递给class方法,这样您就不会试图依赖于无法访问的对象。

编辑:无法确切说出您要更新的预定,而是要全部更新:

# 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

现在,处于更新状态的自我完成是指一个实例...我们在update_reservations_status中最后一次调用的BC。

以上是关于Rails:从另一个模型调用或委托实例方法的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个活动中调用片段

从另一个片段调用一个片段中的方法

使用意图从另一个片段调用一个片段

如何将 View 类中的代码片段移动到 OnAppearing() 方法?

使用 UIView 中的按钮从另一个 ViewController 触发方法

C#中通过委托来调用对象方法的基本过程