Skip to content

Api changes in version 3

Vinicius Ferreira Negrisolo edited this page May 12, 2016 · 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.

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

Expose options

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

-v 2.x

  • Possible options
:ancestor
another exposure to scope from
:model
model to use for that exposure
:params
method to call on the controller to get a params hash
:finder
method used to find the record
:finder_parameter
attribute containing the finder method's unique identifier

-v 3.x

  • Possible options
:fetch
:id
:find
:build
:build_params
:scope
:model
:decorate
  • Use :from in place of :ancestor
  • Use :build_params in place of :params

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_paams) 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