在 Rails 上 Ruby 中保存之前清理模型中的参数

Sanitize parameters in model before save in Ruby on Rails

是否可以清理模型中从控制器传输的参数?

假设我有这个控制器:

class FooController < ApplicationController

  ...

  def new
    @foo||= Foo.new

    render :action => :new
  end


  def create
    @foo= Foo.new(foo_params)

    if @foo.save
      flash[:notice] = 'Foo created'
      redirect_to foo_path(@foo.id)
    else
      new
    end
  end

  ...

  private

  def foo_params
    params.require(:name, :bars => [])
  end
end

和这个模型:

class Foo < ApplicationRecord

end

在这个模型中,我想清理 bars 数组中的参数。 bars 数组包含字符串,但这些字符串只是数字。我想将它们转换成整数。我该怎么做?

感谢所有回答。

使用 before_save 回调,您可以调用一个方法将字符串转换为整数:

class Foo < ApplicationRecord
  before_save :sanitize_bars

  def sanitize_bars
    self.bars = bars.reject(&:empty?).map(&:to_i)
  end
end

在保存 @foo 之前,您可以像这样转换 bars 数组

def create
@foo= Foo.new(foo_params)

# this converts array of strings into integers
@fou.bars = @fou.bars.map(&:to_i)

if @foo.save
  flash[:notice] = 'Foo created'
  redirect_to foo_path(@foo.id)
else
  new
end

结束

以下是改进后的答案。这也将拒绝空字符串。

class Foo < ApplicationRecord
  before_save :sanitize_bars

  def sanitize_bars
    self.bars = bars.reject(&:empty?).map(&:to_i)
  end
end

另一种方法是在模型中为此参数定义属性编写器:

class Foo < ApplicationRecord
  def bars=(value)
    super(value.map(&:to_i))
  end
end

它也很容易测试:

foo = Foo.new(bars: ["1", "2"])
expect(foo.bars).to eq [1, 2]