我有两个型号:
class Continent < ActiveRecord::Base
has_many :countries
end
class Country < ActiveRecord::Base
belongs_to :continent
end
我创建了控制器:
class ContinentsController < ApplicationController
def index
@continents = Continent.all
render json: @continents
end
end
和序列化器:
class ContitnentSerializer < ActiveModel::Serializer
attributes :name, :countries
end
我的问题开始了。我想仅序列化具有给定条件的国家,其中值来自HTTP GET参数。仅当人口超过params [:population]时,才应显示序列化器内的国家/地区。问题出在序列化器内部,我们无法访问params来检查它。
[
{
name: 'Europe'
countries: [
{
name: 'Italy',
population: 1000000
}
]
},
{
name: 'Africa'
countries: [
]
}
]
我试图加入有条件的表,但似乎无法正常工作。
@continents = Continent.all.joins("LEFT JOIN countries ON countries.continent_id = continents.id AND countries.population > #{params[:population]}")
答案 0 :(得分:1)
创建一个范围并使用来自控制器的param
值调用范围:
scope :population_more_than, ->(population) {all.joins("LEFT JOIN countries ON countries.continent_id = continents.id AND countries.population > ?", population)}
现在从控制器而不是Continent.all
Continent.population_more_than(params[:population])
答案 1 :(得分:0)
你可以尝试
@continents = Continent.all
@continents.num_population = params[:population]
render json: @continents.to_json(methods: :countries_with_population_gt)
在Continent
模型中
attr_accessor :num_population
def countries_with_population_gt(num_population=0)
countries.where('population > ?', @num_population)
end
答案 2 :(得分:0)
基本上,您只需要选择属于特定规则的Continent
。如果这是一个经常使用的过滤器,那么我会按照Babar的建议去创建一个范围。
如果这是一次性选择,那么我更喜欢在那里进行过滤而不会使用非常用范围混淆我的模型。
Continent.joins(:countries).where("countries.population > :population", population: params[:population])
# Or event shorter
Continent.joins(:countries).where("countries.population > :population", params)