# Developing Rails plugin: need some metaprog. help

**URL:** <https://www.ruby-forum.com/t/developing-rails-plugin-need-some-metaprog-help/120993>\
**Category:** Ruby\
**Created:** [November 22, 2007, 2:00pm UTC](https://www.ruby-forum.com/t/developing-rails-plugin-need-some-metaprog-help/120993 "2007-11-22T14:00:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 22, 2007, 2:00pm UTC](https://www.ruby-forum.com/t/developing-rails-plugin-need-some-metaprog-help/120993/1 "2007-11-22T14:00:29Z")

</div>

Hi all

I’m developing an authorization plugin that looks like the following so  
far:

module Incense  
module Authorization  
def self.included(base\_class)  
base\_class.extend(ClassMethods)  
end

```
module ClassMethods
  def performs_authorization(options = {})
    before_filter :prepare_user

    include(InstanceMethods)
  end
end

```

end

module InstanceMethods  
private  
def prepare\_user  
session[:user] ||= Member.find\_by\_id(2) # When there’s no user\_id  
in the session, then use #2 for Guest  
…  
end

Because I extracted this functionality from an application, in  
prepare\_user() there’s still a hardwired “Member” model used. But in  
another application I need this to be a “User” model, so I’d like to be  
able to specify the model to use in the options hash of the  
performs\_authorization() method. So how can I achieve this? Do I have to  
use define\_method() in the context of performs\_authorization? This would  
work, I guess, but I don’t like it very much… Isn’t there another way?

Thanks  
Josh

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 22, 2007, 2:01pm UTC](https://www.ruby-forum.com/t/developing-rails-plugin-need-some-metaprog-help/120993/2 "2007-11-22T14:01:45Z")

</div>

Maybe I can pass arguments to include() somehow?

include(InstanceMethods, model\_to\_use)

?

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 22, 2007, 6:46pm UTC](https://www.ruby-forum.com/t/developing-rails-plugin-need-some-metaprog-help/120993/3 "2007-11-22T18:46:38Z")

</div>

> Maybe I can pass arguments to include() somehow?
> 
> include(InstanceMethods, model\_to\_use)

That should be fine. Until you try to access it, it’s just a variable.  
You can have

variable.do\_something()

and then later assign different objects to that variable. e.g.:

def sound(beast)  
beast.make\_noise  
end

and then

sound(Cow) # =\> “moo”  
sound(Dog) # =\> “woof”  
sound(Rabbit) # =\> “squee”

–  
Giles B.

Podcast: [http://hollywoodgrit.blogspot.com](http://hollywoodgrit.blogspot.com)  
Blog: [http://gilesbowkett.blogspot.com](http://gilesbowkett.blogspot.com)  
Portfolio: [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)  
Tumblelog: [http://giles.tumblr.com](http://giles.tumblr.com)

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 23, 2007, 9:00pm UTC](https://www.ruby-forum.com/t/developing-rails-plugin-need-some-metaprog-help/120993/4 "2007-11-23T21:00:40Z")

</div>

Hi Joshua,

> ```
> def performs_authorization(options = {})
> session[:user] ||= Member.find_by_id(2) # When there's no user_id
> 
> ```
> 
> performs\_authorization? This would work, I guess, but I don’t like  
> it very much… Isn’t there another way?

A simple way consists in storing the options hash as a class  
variable, you can then create instance and class method  
to get the class from the options hash :

def performs\_authorization(options = {})  
before\_filter :prepare\_user

cattr\_accessor :options  
self.options = options

include(InstanceMethods)  
end

# give the name you want

def user\_model  
options[:user\_model]  
end

module InstanceMethods  
private  
def user\_model  
self.class.user\_model  
end

def prepare\_user  
session[:user] ||= user\_model.find\_by\_id(2)  
…  
end  
end

HTH,

– Jean-François.

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [November 26, 2007, 10:50am UTC](https://www.ruby-forum.com/t/developing-rails-plugin-need-some-metaprog-help/120993/5 "2007-11-26T10:50:13Z")

</div>

Thank you, Jean-FranÃ§ois! But is this good style? I’m always looking for  
well written patterns, and maybe I should dig deeper into Rails for  
having a better overwiew about how they do things. 🙂
