Jbuilder 没有将单个对象包装在集合中
Jbuilder not wrapping single object in collection
我的 rails 应用程序中有一个索引视图,允许通过搜索参数进行过滤。当一组操作文章被返回时,它被包裹在一个 articles
集合中,如 {"articles":[{"article":{"id":341,"updated":"2015-08-18T13:05:08.427Z","title":"
。但是,如果只找到一个对象,则缺少 articles
级别,{"article":{"id":398,"updated":"2015-08-07T11:37:26.200Z","title":
。我怎样才能修复它,使单个对象的行为像多个对象一样?
_articles.list.json.jbuilder
require 'uri'
require 'publish_on'
json.cache! ['v1', articles] do
json.articles articles do |article|
json.cache! ['v1', article] do
json.article do
json.id article.id
json.updated as_ns_date(article.updated_at)
json.title article.label
json.numberOfViews article.view_mappings.count
json.numberOfFavorites article.favorite_mappings.count
json.imageURLs article.images if article.images.any?
json.youtubeURL article.youtube unless article.youtube.blank?
json.tags article.categories.map(&:label)
json.isFeatured article.featured
json.isPublished article.is_published
json.published as_ns_date(article.publish_on)
end
end
end
end
index.json.jbuilder
json.partial! 'articles/articles_list', articles: @articles
articles_controller.rb
def index
@articles = SearchArticlesCommand.new(params).execute
render :index
end
search_articles_command.rb
class SearchArticlesCommand
def initialize(params = {})
@since = params[:since_date]
@keys = params[:search_query]
@category = params[:category]
end
def execute
Article.unscoped do
query = if @since.present?
Article.article.since_date(@since)
else
Article.published_article
end
query = query.search_by_keywords(@keys) if @keys.present?
query = query.search_by_category(@category) if @category.present?
query.select(:id, :updated_at, :label, :is_published, :featured, :slug, :created_at).order(created_at: :desc)
end
end
end
article.rb
class Article < Comfy::Cms::Page
include PgSearch
include ActionView::Helpers::SanitizeHelper
HOSTNAME = ENV['HOSTNAME'] || Socket.gethostname
has_many :view_mappings, dependent: :destroy
has_many :favorite_mappings, dependent: :destroy
pg_search_scope :search_by_keywords, against: [:content_cache, :label], using: { tsearch: { any_word: true, prefix: true } }
pg_search_scope :search_by_category, associated_against: {
categories: [:label]
}
scope :since_date, -> (date) { where('created_at > ? OR updated_at > ? ', date, date) if date.present? }
scope :folder, -> { where.not(layout_id: ENV['ARTICLE_LAYOUT_ID']) }
scope :published_article, -> { published.article }
scope :article, -> { where(layout_id: ENV['ARTICLE_LAYOUT_ID']) }
这就是我所怀疑的。如果您想要相同的行为,您的查询在找到一篇或多篇文章时应该 return 相同类型的对象。问题是根据您的参数,您正在 returning 一个 ActiveRecordRelation
或 Article
对象。
@articles = Article.all # => ActiveRecordRelation, an array per se
@articles = Article.find(1) # => Article object
当谈到 jbuilder
构造 JSON
时,它会检查它是否是一个对象数组,然后用 { keyword => array }
包裹 json。当是单对象时,默认为单对象{article: {}}
。
解决方案很简单,您可以将 SearchArticlesCommand
调整为始终 return 和 ActiveRecordRelation
,即使它只找到一个对象。
我的 rails 应用程序中有一个索引视图,允许通过搜索参数进行过滤。当一组操作文章被返回时,它被包裹在一个 articles
集合中,如 {"articles":[{"article":{"id":341,"updated":"2015-08-18T13:05:08.427Z","title":"
。但是,如果只找到一个对象,则缺少 articles
级别,{"article":{"id":398,"updated":"2015-08-07T11:37:26.200Z","title":
。我怎样才能修复它,使单个对象的行为像多个对象一样?
_articles.list.json.jbuilder
require 'uri'
require 'publish_on'
json.cache! ['v1', articles] do
json.articles articles do |article|
json.cache! ['v1', article] do
json.article do
json.id article.id
json.updated as_ns_date(article.updated_at)
json.title article.label
json.numberOfViews article.view_mappings.count
json.numberOfFavorites article.favorite_mappings.count
json.imageURLs article.images if article.images.any?
json.youtubeURL article.youtube unless article.youtube.blank?
json.tags article.categories.map(&:label)
json.isFeatured article.featured
json.isPublished article.is_published
json.published as_ns_date(article.publish_on)
end
end
end
end
index.json.jbuilder
json.partial! 'articles/articles_list', articles: @articles
articles_controller.rb
def index
@articles = SearchArticlesCommand.new(params).execute
render :index
end
search_articles_command.rb
class SearchArticlesCommand
def initialize(params = {})
@since = params[:since_date]
@keys = params[:search_query]
@category = params[:category]
end
def execute
Article.unscoped do
query = if @since.present?
Article.article.since_date(@since)
else
Article.published_article
end
query = query.search_by_keywords(@keys) if @keys.present?
query = query.search_by_category(@category) if @category.present?
query.select(:id, :updated_at, :label, :is_published, :featured, :slug, :created_at).order(created_at: :desc)
end
end
end
article.rb
class Article < Comfy::Cms::Page
include PgSearch
include ActionView::Helpers::SanitizeHelper
HOSTNAME = ENV['HOSTNAME'] || Socket.gethostname
has_many :view_mappings, dependent: :destroy
has_many :favorite_mappings, dependent: :destroy
pg_search_scope :search_by_keywords, against: [:content_cache, :label], using: { tsearch: { any_word: true, prefix: true } }
pg_search_scope :search_by_category, associated_against: {
categories: [:label]
}
scope :since_date, -> (date) { where('created_at > ? OR updated_at > ? ', date, date) if date.present? }
scope :folder, -> { where.not(layout_id: ENV['ARTICLE_LAYOUT_ID']) }
scope :published_article, -> { published.article }
scope :article, -> { where(layout_id: ENV['ARTICLE_LAYOUT_ID']) }
这就是我所怀疑的。如果您想要相同的行为,您的查询在找到一篇或多篇文章时应该 return 相同类型的对象。问题是根据您的参数,您正在 returning 一个 ActiveRecordRelation
或 Article
对象。
@articles = Article.all # => ActiveRecordRelation, an array per se
@articles = Article.find(1) # => Article object
当谈到 jbuilder
构造 JSON
时,它会检查它是否是一个对象数组,然后用 { keyword => array }
包裹 json。当是单对象时,默认为单对象{article: {}}
。
解决方案很简单,您可以将 SearchArticlesCommand
调整为始终 return 和 ActiveRecordRelation
,即使它只找到一个对象。