require 'toy/proxies/proxy' module Toy module Proxies class List < Toy::Proxies::Proxy def get(id) if target_ids.include?(id) proxy_class.get(id) end end def get!(id) get(id) || raise(Toy::NotFound.new(id)) end def include?(record) return false if record.nil? target_ids.include?(record.id) end def push(record) assert_type(record) self.target_ids = target_ids + [record] end alias :<< :push def concat(*records) records = records.flatten records.map { |record| assert_type(record) } self.target_ids = target_ids + records end def replace(records) reset self.target_ids = records end def create(attrs={}) if proxy_options[:inverse_of] attrs.update(:"#{proxy_options[:inverse_of]}_id" => proxy_owner.id) end proxy_class.create(attrs).tap do |record| if record.persisted? proxy_owner.reload push(record) proxy_owner.save reset end end end def destroy(*args, &block) ids = block_given? ? target.select(&block).map(&:id) : args.flatten proxy_class.destroy(*ids) proxy_owner.reload self.target_ids = target_ids - ids proxy_owner.save reset end def destroy_all proxy_class.destroy(*target_ids) self.target_ids = [] proxy_owner.save reset end def reset @target = nil end private def find_target return [] if target_ids.blank? proxy_class.get_multi(target_ids) end def target_ids proxy_owner.send(proxy_key) end def target_ids=(value) ids = value.map do |item| if item.is_a?(proxy_class) item.id elsif item.is_a?(Hash) item['id'] else item end end proxy_owner.send(:"#{proxy_key}=", ids) reset end end end end