开发者

Need help with a code smell

In my Rails application I'm trying to make the controllers skinnier and am having difficulty with one object that I keep having to pass around.

The object represents a user's facebook session and is instantiated off of the session so it exists in the controller side of things. Many model methods use it, so it is repeatedly passed in as an argument all over the place.

开发者_开发知识库

This smells like something, how to DRY it up the Rails way? Thanks!


First, I would recommend using a system similar to Authlogic for your authentication. This gives you two bonuses:

  • You have proven, stable, tested authentication for your application
  • The sessions are based like Models, so you can do this kind of stuff...

class Widget < ActiveRecord::Base
  def do_facebook_stuff
    UserSession.find #This gets you the current session
    UserSession.find.record # This gets your the user for the current session
  end
end

Now you no longer need to pass the session information in, as you can do basic model-style lookups to find it. In addition to this, Authlogic has a plugin architecture that supports Facebook Connect, which may help you further.


I can give you the CakePHP way (which was originally designed to be like rails).

All CakePHP models extend the same parent AppModel, and all controllers extend an AppController.

I would make an empty parameter in the AppModel that represents your object. Then in the AppController I would store the object in the current model's parameter, if the object exists. There is a callback in the CakePHP AppController called beforeFilter() which fires before any code in the controller. The ideal place to check for the object and store it in the model would be in whatever equivalent Rails has of this beforeFilter callback.

That is unless all models don't use the object. If that is true, you could put the parameter in only the Models that use it (instead of the parent), and then in the beforeFilter of the AppModel you can check first if the Model has that empty parameter.

I know it's not Ruby, but it would look like this:

public function beforeFilter() {
    if (isset($this->{$this->modelName}->yourObjectParameter)) {
        $this->{$this->modelName}->yourObjectParameter = $this->yourObject;
    }
}

$this->modelName is a string that corresponds to the name of the current model. the { } around $this->modelName in PHP is called complex syntax. It basically converts the string into the model object. Not sure how to do the same thing in Ruby.


You can take your method to application controller, something like this

class ApplicationController < ActionController::Base

before_filter :get_facebook_session

def get_facebook_session

@facebook_session = <your code >

end

end

And you can access @facebook_session variable from your controllers and views

cheers

sameera

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜