How to achieve strong parameter protection without Rails?

651 Views Asked by At

I am developing a boilerplate web application with Goliath + Grape + Active Record 4.2 + Active Record Migrations. Here is my migration file

# db/migrate/20150519063210_create_albums.rb
class CreateAlbums < ActiveRecord::Migration
  def change
    create_table :albums do |t|
      t.string :name
      t.string :artist
      t.string :genre
      t.date :published_at
    end
  end
end

And my model

# app/models/Album
class Album < ActiveRecord::Base
end

And the Grape API

class ApiV1 < Grape::API
  version 'v1', using: :path
  format :json

  resource 'albums' do
    get '/' do
      Album.all
    end

    post '/' do
      Album.create(params[:album])  # <-- raises ActiveModel::ForbiddenAttributesError
    end
  end
end

When I call POST /v1/albums/ with some parameters, the application always raises ActiveModel::ForbiddenAttributesError. It seem that ActiveRecord wants ActionController::Parameters to be the arguments, but Grape gives it Hashie::Mash.

I've tried implementing a simple Rack middleware to convert env['params'] from a Hash to a ActionController::Parameters and using it after Goliath::Rack::Params, but Grape just sanitizes it out when the helper method params is called. I also tried implementing and using a Grape middleware to do the same thing and got the same result.

Is there any solution on this or I just have to down grade to ActiveRecord 3?

1

There are 1 best solutions below

1
On BEST ANSWER

You could create a helper to generate an instance of ActionController::Parameters with your parameters:

require 'action_controller/metal/strong_parameters' 

class ApiV1 < Grape::API
  version 'v1', using: :path
  format :json

  helpers do
    def albums_params
      ActionController::Parameters.new(params).require(:album).permit(:attr1, :attr2)
    end
  end

  resource 'albums' do
    get '/' do
      Album.all
    end

    post '/' do
      Album.create(albums_params)
    end
  end
end

Or you can use the hashie-forbidden_attributes gem.