class Item class Proxy include FragmentLocalization attr_reader :id attr_writer :item, :owned, :wanted delegate :description, :name, :nc?, :thumbnail_url, :to_param, to: :item def self.model_name Item.model_name end def initialize(item_or_id) if item_or_id.is_a? Item @item = item_or_id @id = @item.id else @id = item_or_id.to_i end @known_outputs = {method: {}, partial: {}} end def as_json(options={}) cache_method(:as_json, include_hanger_status: false).tap do |json| json[:owned] = owned? json[:wanted] = wanted? end end def owned? @owned end def to_partial_path # HACK: could break without warning! Item._to_partial_path end def wanted? @wanted end def fragment_key(type, name) prefix = type == :partial ? 'views/' : '' base = localize_fragment_key("items/#{@id}##{name}", I18n.locale) prefix + base end def set_known_output(type, name, value) @known_outputs[type][name] = value end def known_partial_output(name) @known_outputs[:partial][name] end private def cache_method(method_name, *args, &block) # Two layers of cache: a local copy, in case the method is called again, # and then the Rails cache, before we hit the actual method call. @known_outputs[:method][method_name] ||= begin key = fragment_key(:method, method_name) Rails.cache.fetch(key) { item.send(method_name, *args) } end end def item @item ||= Item.find(@id) end end end