4

I've been trying Padrino framework in one of my project, and there is one thing that really annoys me. I want to implement just for instance a user registration process using OmniAuth and want to break my request handler (controller's action) to separate methods, like this:

get ":provider/callback" do
  @user = find_the_user_by_oauth(request)
  create_user unless @user
  store_user_in_session
end

def find_the_user_by_oauth(request)
  #...
end

def store_user_in_session
  session[:user_id] = @user.id
end

I know it would be nicer to push the logic to the model layer, but my question is, how could I break a controller logic to separated methods and share information among them (like using instance variables). In Rails I created these methods in the private scope of my controller, but here I should extend the Application class because it throws Undefined method exception for the previous code. I tried Helpers, but helpers don't know the instance variables, so you should pass the variables every time.

What is the good way to make my controller actions clean in Padrino?

Nucc
  • 1,031
  • 6
  • 20

2 Answers2

12

To define a method inside an Padrino Controller you can use define_method instead of def.

For your example, do something like this:

Admin.controllers :dummy do

  define_method :find_the_user_by_oauth do |request|
    request.params["username"]
    # ...
  end

  define_method :store_user_in_session do
    session[:user_id] = @user
  end

  get :test do
    @user = find_the_user_by_oauth(request)
    create_user unless @user
    store_user_in_session()
    session.inspect
  end

end

Padrino runs the block sent to Admin.controllers using instance_eval. See this answer for the differences https://stackoverflow.com/a/3171649 between define_method and def

Community
  • 1
  • 1
lz.
  • 331
  • 3
  • 10
-2

possible offtopic, but would you consider to use Espresso Framework instead.

then you'll can solve your issue as simple as:

class App < E

  def index provider, action = 'callback'
    @user = find_the_user_by_oauth
    create_user unless @user
    store_user_in_session
  end

  private

  def find_the_user_by_oauth
    # provider, action are accessed via `action_params`
    # action_params[:provider]
    # action_params[:action]
  end

  def store_user_in_session
    session[:user_id] = @user.id
  end

end
alfred jon
  • 115
  • 1
  • 1
  • 10
  • I don't want to use other framework. The support for Padrino is good, I would like to use gems which are fully compatible with my framework, and I guess with Espresso I will have some unexpected issues. – Nucc Nov 11 '12 at 12:45
  • sure, you decide, i do not insist, it was just a innocent suggestion. – alfred jon Nov 11 '12 at 12:50
  • mm, what do you mean by "unexpected issues"? Espresso are so simple as Ruby are. Using it for about 2 months and had no issues or surprises so far. Great documentation, which in fact is rarely needed cause everything is done in seamless Ruby way. – alfred jon Nov 11 '12 at 12:54
  • Usually for popular gems somebody creates a framework specific version to be easier to integrate to the framework. I don't know Espresso, and don't know how many unexpected issues I will have when a gem not fully compatible with espresso and I can't use one of the mygemname-espresso framework specific gem (like omniauth-padrino gem with padrino). – Nucc Nov 11 '12 at 13:03