尝试使用 to_json 生成嵌套 json 格式时,rails 上的 ruby 中出现未定义方法错误?
Undefined Method Error in ruby on rails, when trying to produce a nested json format using to_json?
这是我的 gems lib s4s 模型文件夹中的产品模型:
module S4s
module Models
class Product < ActiveRecord::Base
self.table_name = 'product'
has_many :images, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
has_many :primary_images, -> { where(primary_image: true) }, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
has_one :image, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
has_many :product_images, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
end
end
end
这是我的 gems lib s4s 模型文件夹中的 product_image.rb 文件:
require 'paperclip'
module S4s
module Models
class ProductImage < ActiveRecord::Base
self.table_name = 'product_images'.freeze
include S4s::Models::Concerns::Upload
TYPE_HIGH_RESOLUTION = 'highResolution'
TYPE_ADDITIONAL = 'additional'
IMAGE_VERSIONS = %w|mini small medium xs sm fullxs fullsm large|
attr_accessor :image_file_size
alias_attribute :image_file_name, :original_file_name
alias_attribute :image_content_type, :file_ext
alias_attribute :image_updated_at, :updated_at
belongs_to :product, foreign_key: 'product_id'.freeze, class_name: 'S4s::Models::Product'.freeze
belongs_to :color, foreign_key: 'color_id'.freeze, class_name: 'S4s::Models::Dictionary::Color'.freeze
validates :title, presence: true
scope :additional, -> { where(image_type: TYPE_ADDITIONAL) }
scope :high_resolution, -> { where(image_type: TYPE_HIGH_RESOLUTION) }
scope :primary_images, -> { where(primary_image: true) }
after_initialize :set_default_value
after_save :set_product_colors!
add_attachment :image,
styles: {
mini: ['100x100#', :jpg],
small: ['220x220#', :jpg],
medium: ['380x380#', :jpg],
xs: ['240x240', :jpg],
sm: ['348x348#', :jpg],
fullxs: ['480x480#', :jpg],
fullsm: ['768x768#', :jpg],
large: ['1000x1000', :jpg],
},
path_block: -> (style) { self.build_path(style) },
matches: /(png|jpe?g|gif)/i
# Populate file_name attribute with the current title
before_image_post_process :set_file_name!
public
def url(type = 'mini')
return nil unless self.product_id.present?
image.url(type)
end
def urls
Hash[IMAGE_VERSIONS.map { |v| [v, self.url(v)] }]
end
def as_json(opts = {})
{
id: self.id,
is_primary_image: primary_image?,
product_id: self.product_id,
title: self.title,
color: 'n/a',
sku: self.sku,
position: self.position,
image_type: self.image_type,
urls: self.urls
}
end
def build_path(style)
return nil if product.nil?
build_asset_path(style, !(new_system? || title_used?))
end
private
def build_asset_path(style, old_format = false)
"/products/#{product_id}/#{build_slug(old_format)}-#{style}.#{_find_extension(image_content_type)}"
end
def build_slug(old_format)
if old_format && !file_name.present?
"#{product.name.parameterize}#{position > 0 ? "-#{position}" : ''}"
else
file_name
end
end
def set_product_colors!
_colors = self.product.images.map(&:color).compact
if self.product.colors.map(&:id).sort != _colors.map(&:id).sort
self.product.update_attribute :colors, _colors
end
end
def set_file_name!
self.file_name = SecureRandom.hex(20)
self.new_system = true
end
def set_default_value
self.position ||= 0
self.new_system = true if self.new_system.nil?
end
end
end
end
逻辑是我们使用 S4s::Models::ModelName
将这些模型调用到不同的应用程序
下面是我用来渲染的控制器文件json(这个控制器在另一个应用程序中):
class HalfsController < ApplicationController
def index
@hotspot = S4s::Models::Product.all
render json: @hotspot.to_json(include: :product_images)
end
...
end
我需要在产品对象中使用 Product_image 对象的嵌套格式。
我是 ruby 和 rails 框架的新手,请帮助我。
注意:我已经尝试了所有格式 to_json,例如 :product_images 和 :product_image.. 嵌套适用于 gems 中的许多其他模型,但这些不适用于产品和 product_images.. 他们使用回形针上传和生成图像 url
尝试render json: @hotspot.as_json(include: :product_images)
我知道 to_json 在内部调用 as_json,但如果您覆盖 to_json,它将不包括关联。 (我认为)。
这是我的 gems lib s4s 模型文件夹中的产品模型:
module S4s
module Models
class Product < ActiveRecord::Base
self.table_name = 'product'
has_many :images, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
has_many :primary_images, -> { where(primary_image: true) }, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
has_one :image, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
has_many :product_images, foreign_key: :product_id, class_name: 'S4s::Models::ProductImage'
end
end
end
这是我的 gems lib s4s 模型文件夹中的 product_image.rb 文件:
require 'paperclip'
module S4s
module Models
class ProductImage < ActiveRecord::Base
self.table_name = 'product_images'.freeze
include S4s::Models::Concerns::Upload
TYPE_HIGH_RESOLUTION = 'highResolution'
TYPE_ADDITIONAL = 'additional'
IMAGE_VERSIONS = %w|mini small medium xs sm fullxs fullsm large|
attr_accessor :image_file_size
alias_attribute :image_file_name, :original_file_name
alias_attribute :image_content_type, :file_ext
alias_attribute :image_updated_at, :updated_at
belongs_to :product, foreign_key: 'product_id'.freeze, class_name: 'S4s::Models::Product'.freeze
belongs_to :color, foreign_key: 'color_id'.freeze, class_name: 'S4s::Models::Dictionary::Color'.freeze
validates :title, presence: true
scope :additional, -> { where(image_type: TYPE_ADDITIONAL) }
scope :high_resolution, -> { where(image_type: TYPE_HIGH_RESOLUTION) }
scope :primary_images, -> { where(primary_image: true) }
after_initialize :set_default_value
after_save :set_product_colors!
add_attachment :image,
styles: {
mini: ['100x100#', :jpg],
small: ['220x220#', :jpg],
medium: ['380x380#', :jpg],
xs: ['240x240', :jpg],
sm: ['348x348#', :jpg],
fullxs: ['480x480#', :jpg],
fullsm: ['768x768#', :jpg],
large: ['1000x1000', :jpg],
},
path_block: -> (style) { self.build_path(style) },
matches: /(png|jpe?g|gif)/i
# Populate file_name attribute with the current title
before_image_post_process :set_file_name!
public
def url(type = 'mini')
return nil unless self.product_id.present?
image.url(type)
end
def urls
Hash[IMAGE_VERSIONS.map { |v| [v, self.url(v)] }]
end
def as_json(opts = {})
{
id: self.id,
is_primary_image: primary_image?,
product_id: self.product_id,
title: self.title,
color: 'n/a',
sku: self.sku,
position: self.position,
image_type: self.image_type,
urls: self.urls
}
end
def build_path(style)
return nil if product.nil?
build_asset_path(style, !(new_system? || title_used?))
end
private
def build_asset_path(style, old_format = false)
"/products/#{product_id}/#{build_slug(old_format)}-#{style}.#{_find_extension(image_content_type)}"
end
def build_slug(old_format)
if old_format && !file_name.present?
"#{product.name.parameterize}#{position > 0 ? "-#{position}" : ''}"
else
file_name
end
end
def set_product_colors!
_colors = self.product.images.map(&:color).compact
if self.product.colors.map(&:id).sort != _colors.map(&:id).sort
self.product.update_attribute :colors, _colors
end
end
def set_file_name!
self.file_name = SecureRandom.hex(20)
self.new_system = true
end
def set_default_value
self.position ||= 0
self.new_system = true if self.new_system.nil?
end
end
end
end
逻辑是我们使用 S4s::Models::ModelName
将这些模型调用到不同的应用程序下面是我用来渲染的控制器文件json(这个控制器在另一个应用程序中):
class HalfsController < ApplicationController
def index
@hotspot = S4s::Models::Product.all
render json: @hotspot.to_json(include: :product_images)
end
...
end
我需要在产品对象中使用 Product_image 对象的嵌套格式。 我是 ruby 和 rails 框架的新手,请帮助我。
注意:我已经尝试了所有格式 to_json,例如 :product_images 和 :product_image.. 嵌套适用于 gems 中的许多其他模型,但这些不适用于产品和 product_images.. 他们使用回形针上传和生成图像 url
尝试render json: @hotspot.as_json(include: :product_images)
我知道 to_json 在内部调用 as_json,但如果您覆盖 to_json,它将不包括关联。 (我认为)。