Rails - 序列化相关数据

时间:2016-04-13 12:36:56

标签: sql ruby-on-rails ruby serialization

我有两个型号:

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]}")

3 个答案:

答案 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)