Skip to content

Api changes in version 3

Matt Polito edited this page Mar 30, 2020 · 29 revisions

Plurals

-v 2.x

class Controller
  expose(:person)
end

-v 3.x

In version 3, plural helpers are not automatically generated. Now collections must be explicitly exposed. Singular exposures are also no longer scoped by the plural exposure as it previously had.

class Controller
  expose(:people, -> { Person.all })
  expose(:person)
end

Expose options

expose(name, options = {}, &block)

-v 2.x

  • Possible options
:ancestor
:model
:params
:finder
:finder_parameter
:attributes

-v 3.x

  • Possible options
:fetch
:id
:find
:build
:build_params
:scope
:model
:decorate

In order to migrate consider:

  • Use :from in place of :ancestor
  • Use :build_params in place of :params
  • Remove :attributes

The implementation of build_params will call thing_params (if you expose thing) just if it's not a GET request. That's because thing_params method should use Rails Strong Parameters which can require a parameter to be present. That's usually not the case for GET calls, which query parameters are usually optional. In this case you may define build_params.

:attributes is not necessary anymore because decent_exposure will call your thing_params method if you define it. So there's no need for defining that anymore. If you still need to call another method consider to use :build_params options.

Instead of using :finder and :finder_parameter like this:

class PeopleController < ApplicationController
  expose(:people, finder: :find_by_slug, finder_parameter: :slug)
end

This is now equivalent to:

class PeopleController < ApplicationController
  expose :people, find_by: :slug, id: :slug
end

Strategies

Strategies from 2.x can now be implemented ::exposure_config

-v 2.x

class CurrentUserStrategy < DecentExposure::Strategy
  delegate :current_user, to: :controller

  def resource
    instance = model.find(params[:id])

    if current_user != instance.user
      raise ActiveRecord::RecordNotFound
    end

    instance
  end
end

class PostsController < ApplicationController
  expose :post, strategy: CurrentUserStrategy
end

-v 3.x

class PostsController < ApplicationController
  exposure_config :current_user_strategy, find: ->(id, scope){
    post = scope.find(id)

    if current_user != post.user
      raise ActiveRecord::RecordNotFound
    end

    post
  }

  expose :post, with: :current_user_strategy
end

Problems you may face upgrading:

undefined method `decent_configuration'

If you have set in your ApplicationController to work with strong parameters you can just remove this code:

# v 2.x
class ApplicationController < ActionController::Base
  decent_configuration do
    strategy DecentExposure::StrongParametersStrategy
  end
end

And you should implement explicitly your #{exposed_thing}_params method like:

# v 3.x
class ThingController < ApplicationController
  def thing_params
    params.require(:thing).permit(:foo, :bar)
  end
end

If you had something like this Strategy:

# v 2.x
class VerifiableStrategy < DecentExposure::Strategy
  delegate :current_user, :to => :controller

  def resource
    instance = model.find(params[:id])
    if current_user != instance.user
      raise ActiveRecord::RecordNotFound
    end
    instance
  end
end

You can replace it with a simple scope:

# v 3.x
class ThingController < ApplicationController
  expose :thing, scope: ->{ current_user.things }
end

For other usages decent_configuration was replaced by exposure_config feature. Also you can move your Strategy code and expose it as exposure_config.

undefined method `each' for #Thing:0x007fbe048bbab8

If you had this kind of code:

# v 2.x
class ThingController < ApplicationController
  expose :things
  expose :thing
end

Now you need to explicitly define the plural way to fetch data. There is no more pluralization inflection in decent_exposure.

# v 3.x
class ThingController < ApplicationController
  expose :things, ->{ Post.all }
  expose :thing
end

Update does not save any changes

You need to explicitly call thing.update(thing_params) instead of just thing.save on update controller action. Additionally you can remove the options attributes. So if you have this code:

# v 2.x
class ThingsController < ApplicationController
  expose(:thing, attributes: :thing_params)

  def update
    if thing.save
      redirect_to(thing)
    else
      render :edit
    end
  end

  def thing_params
    params.require(:thing)
  end
end

You need to change to something like:

# v 3.x
class ThingsController < ApplicationController
  expose(:thing)

  def update
    if thing.update(thing_params)
      redirect_to(thing)
    else
      render :edit
    end
  end

  def thing_params
    params.require(:thing)
  end
end

uninitialized constant MyModel

If your model classes are scoped by a namespace like Blog::Post you must specify it on the expose call with model:

# v 3.x
class Blog::PostsController < ApplicationController
  expose(:post, model: Blog::Post)
end