Daniel
Daniel

Reputation: 359

Sanitize parameters in model before save in Ruby on Rails

is it possible to Sanitize the params transfered from the controller in the model?

Let's say I have this Controller:

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

and this model:

class Foo < ApplicationRecord

end

In this model I want to sanitize the parameters in the bars array. The bars array contains Strings, but these Strings are just numbers. I want to convert them into integers. How do I do that?

All answers are appreciated.

Upvotes: 0

Views: 1537

Answers (4)

Hackman
Hackman

Reputation: 1719

With a before_save callback you can call a method to turn the strings into integers:

class Foo < ApplicationRecord
  before_save :sanitize_bars

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

Upvotes: 0

nuaky
nuaky

Reputation: 2086

Another approach is to define attribute writer in model for this param:

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

Its also easy to test:

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

Upvotes: 2

Suraj Rajput
Suraj Rajput

Reputation: 156

Below is the improved answer. This will also reject the empty strings.

class Foo < ApplicationRecord
  before_save :sanitize_bars

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

Upvotes: 3

Bouaik Lhoussaine
Bouaik Lhoussaine

Reputation: 574

Before saving @foo you can convert the bars array like this

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

end

Upvotes: 0

Related Questions