在我的 Rails 應用程式中。我有一個模塊,我在其中覆寫了.eql?如下所示的方法
# lib/item_util.rb
module ItemUtil
def eql?(item, field: "cost", op: "==")
item.send(field).present? &&
item.send(field).send(op, self.send(field))
end
end
包含在Item模型中
# app/models/item.rb
class Item < ApplicationRecord
include ItemUtil
end
在我的控制器中,我想根據屬性值檢查各種條件。前任:
@item1 = Item.find(:id)
@item2 = Item.find(:id)
@item1.eql?(@item2, field: "discount", op: ">") # @item2.discount > @item1.discount
@item2.eql?(@item1, op: "<=") # @item1.cost <= @item2.cost
# ...
所有這些都作業正常,我想以ItemUtil更簡潔的方式撰寫模塊,如下所示:
module ItemUtil
attr_accessor :item, :field
def initialize(item, field: "cost")
@item = item
@field = field
end
def eql?(item, field: "cost", op: "==")
new_item.present? && new_item.send(op, current_item)
end
def new_item
@item.send(@field)
end
def current_item
self.send(@field)
end
end
這回報TypeError (nil is not a symbol nor a string)了@field里面new_item的方法,因為initialize沒有任何地方呼叫
Traceback (most recent call last):
2: from lib/item_util.rb:12:in `eql?'
1: from lib/item_util.rb:17:in `new_item'
TypeError (nil is not a symbol nor a string)
但我不想改變我呼叫.eql?物件的方式,即,我想保持這些行完好無損
@item1.eql?(@item2, field: "discount", op: ">") # @item2.discount > @item1.discount
@item2.eql?(@item1, op: "<=") # @item1.cost <= @item2.cost
- 如何獲取
new_item并current_item回傳所需的輸出? - 如何
initialize在.eql?方法中呼叫方法? - 有沒有替代方法?
- 有沒有辦法訪問類似于
before_action(在控制器中)的模塊中的引數?
uj5u.com熱心網友回復:
您不能實體化模塊的實體。(您可以實體化類的實體,但不能實體化模塊。)
事實上,你在這里實際做的是覆寫Item#initialize!!的定義。
堅持你的一般設計模式,我建議是將這個邏輯抽象成一個新的類——比如ItemComparator:
class ItemComparator
attr_reader :item, :other
def initialize(item, other)
@item = item
@other = other
end
def eql?(field:, op:)
item_field = item.send(field)
other_field = other.send(:field)
other_field.present? && item_field.send(op, other_field)
end
end
module ItemUtil
def eql?(other, field: "cost", op: "==")
ItemComparator.new(self, other).eql?(field: field, op: op)
end
end
class Item < ApplicationRecord
include ItemUtil
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/314936.html
標籤:红宝石轨道 红宝石 ruby-on-rails-6.1
