4

How can I avoid duplicate code?

resource 'api/publication/:publicationName' do

  params do
    requires :type, type: String, regexp: /^(static|dynamic)$/i
    requires :name, type: String, regexp: /^[a-z0-9_\s]+$/i
    requires :liveStartDate, type: String, regexp: dateRegexp
    optional :liveEndDate, type: String, regexp: dateRegexp
    requires :query, type: String
  end
  post '/dynamic' do
    authenticate!
    save_or_update(params)
  end

  params do
    requires :type, type: String, regexp: /^(static|dynamic)$/i
    requires :name, type: String, regexp: /^[a-z0-9_\s]+$/i
    requires :liveStartDate, type: String, regexp: dateRegexp
    optional :liveEndDate, type: String, regexp: dateRegexp
    requires :query, type: String
  end
  put '/dynamic/:id' do
    authenticate!
    save_or_update(params)
  end

end
hfossli
  • 22,616
  • 10
  • 116
  • 130

2 Answers2

6

In more recent versions of Grape, you can create reusable named groups of parameters. For example:

resource 'api/publication/:publicationName' do
  helpers do
    params :common do
      requires :type,          type: String, regexp: /^(static|dynamic)$/i
      requires :name,          type: String, regexp: /^[a-z0-9_\s]+$/i
      requires :liveStartDate, type: String, regexp: dateRegexp
      optional :liveEndDate,   type: String, regexp: dateRegexp
      requires :query,         type: String
    end
  end

  params do
    use :common
  end
  post '/dynamic' do
    authenticate!
    save_or_update(params)
  end

  params do
    use :common
  end
  put '/dynamic/:id' do
    authenticate!
    save_or_update(params)
  end
end

One advantage of doing things this way is that you can mix different groups of parameters by including multiple use statements for different named params.

Matt Zukowski
  • 4,469
  • 4
  • 37
  • 38
  • I get an error ```ArgumentError - wrong number of arguments (1 for 0):``` I am using grape 0.10.1. Which version are you using? You should do it like this. ```class API < Grape::API helpers do params :pagination do optional :page, type: Integer optional :per_page, type: Integer end end desc "Get collection" params do use :pagination # aliases: includes, use_scope end get do Collection.page(params[:page]).per(params[:per_page]) end end``` – Chun Yang Mar 17 '15 at 20:44
  • @ChunYang, you're right. I've corrected the sample code so that the named params are nested in a helpers block. More info here: https://github.com/ruby-grape/grape#helpers – Matt Zukowski Sep 30 '15 at 01:35
3

Try this:

resource 'api/publication/:publicationName' do
  common_params = Proc.new do
    requires :type,          type: String, regexp: /^(static|dynamic)$/i
    requires :name,          type: String, regexp: /^[a-z0-9_\s]+$/i
    requires :liveStartDate, type: String, regexp: dateRegexp
    optional :liveEndDate,   type: String, regexp: dateRegexp
    requires :query,         type: String
  end

  params(&common_params)
  post '/dynamic' do
    authenticate!
    save_or_update(params)
  end

  params(&common_params)
  put '/dynamic/:id' do
    authenticate!
    save_or_update(params)
  end
end
oldhomemovie
  • 14,621
  • 13
  • 64
  • 99