简体   繁体   中英

How to use as_json to use a method within an association

Imagine I have the following Models:

class Voice
  include Mongoid::Document
  ...
  has_and_belongs_to_many :productions
  ...
  def define_user_currency
  ...
  end
end

class Production
  include Mongoid::Document
  ...
  has_and_belongs_to_many :voices
  ...
  def production_currency
  ...
  end
end

I'd like to get all Voices including all productions and call the define_user_currency on each Voice as well as production_currency on each Production. I've tried the following (I've added this method on Voice ):

def_custom_format
  self.as_json(
    method: self.define_user_currency(currency, ip),
    include: [:builder_types, :voice_types, :preferences, :languages, :productions => {:methods => production_currency(currency, ip)}],
    except: [:avatar_content_type, :avatar_file_size, :avatar_file_name, :avatar_fingerprint, :avatar_updated_at, :voice_content_type, :voice_file_size, :voice_fingerprint, 
    :voice_updated_at, :artist_id, :price_per_word_GBP, :price_per_word_EUR, :price_per_word_USD, :price_GBP, :price_EUR, :price_USD, :categories_name, :category_ids, :production_ids, 
    :language_ids, :preference_ids, :voice_type_ids, :builder_type_ids]
  )
end

But Production is not coming within Voice and I get Undefined method production_currency . If I try include: [:builder_types, :voice_types, :preferences, :languages, :productions => {:methods => self.production_currency(currency, ip)}], I get the same result.

How can I apply the production_method on each production?

It would be possible if your method production_currency(currency, ip) did not take any arguments. Its not possible to send aruguements as there is no way to send comma separated values like

methods: :production_currency, currency, ip
# or
methods: "production_currency(#{currency},#{ip})"

See code

 Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) }

https://github.com/rails/rails/blob/5b368010f64106f7b87a4306b41adcefa856ab67/activemodel/lib/active_model/serialization.rb#L110

Why don't you try this. Make production_currency gather required info from association it self. like

def production_currency
  currency = self.voice.currency
  ip = self.voice.ip
end

and

:productions => {:methods => :production_currency}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM