# Difficulties in understanding Rail-Plugins in depth

**URL:** <https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727>\
**Category:** Rails\
**Created:** [December 27, 2009, 11:55pm UTC](https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727 "2009-12-27T23:55:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![k-b](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/db5fbb/32.png) [@k-b](https://www.ruby-forum.com/u/k-b)\
**Post date:** [December 27, 2009, 11:55pm UTC](https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727/1 "2009-12-27T23:55:28Z")

</div>

Hi,

i try to understand how plugins work in detail.

Often you see stuff like:

class Post \< ActiveRecord::Base  
acts\_as\_commentable  
end

I wonder what’s happen all there.

What kind of language-feature is behind this call “acts\_as\_commentable”  
?  
In my opinion you need some kind of extend or include to extend the  
functionality of a model. And exactly this is which i found in a file  
of the plugin.

> <https://github.com/jackdempsey/acts_as_commentable/blob/master/lib/commentable_methods.rb>

I have found this part:  
module Juixe  
module Acts #:nodoc:  
module Commentable #:nodoc:  
module ClassMethods  
def acts\_as\_commentable  
has\_many :comments, :as =\> :commentable, :dependent =\>  
:destroy  
include Juixe::Acts::Commentable::InstanceMethods  
extend Juixe::Acts::Commentable::SingletonMethods  
end  
end

Is this where the magic happens? I think so. This is really  
ingeniously because you have to just write one line of code to extend  
your other Class.

But now - on the core of the whole thing - there is my question: Why  
does the Class which calls acts\_as\_commentable now that he has to  
chose exactly this method within module Juixe, within Acts, within  
Commentable modules?

Is there a convention for this?

Greetings  
Klaus

–

You received this message because you are subscribed to the Google  
Groups “Ruby on Rails: Talk” group.  
To post to this group, send email to removed\_email\_address@domain.invalid.  
To unsubscribe from this group, send email to  
removed\_email\_address@domain.invalid.  
For more options, visit this group at  
[http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

---

<div class="post-metadata">

**Author:** ![k-b](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/db5fbb/32.png) [@k-b](https://www.ruby-forum.com/u/k-b)\
**Post date:** [December 28, 2009, 12:42am UTC](https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727/2 "2009-12-28T00:42:17Z")

</div>

On Dec 27, 10:54 pm, klaus [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I wonder what’s happen all there.  
> module Acts #:nodoc:  
> ingeniously because you have to just write one line of code to extend  
> your other Class.
> 
> But now - on the core of the whole thing - there is my question: Why  
> does the Class which calls acts\_as\_commentable now that he has to  
> chose exactly this method within module Juixe, within Acts, within  
> Commentable modules?

You’ll see why at the bottom of the same file:

```
ActiveRecord::Base.send(:include, Juixe::Acts::Commentable)

```

That module is being included into ActiveRecord::Base, which is the  
superclass of Post above, making the method available in that context.  
There’s nothing particularly special about the name or location of the  
module - it’s the fact that it’s being included that is important.

- James

–

You received this message because you are subscribed to the Google  
Groups “Ruby on Rails: Talk” group.  
To post to this group, send email to removed\_email\_address@domain.invalid.  
To unsubscribe from this group, send email to  
removed\_email\_address@domain.invalid.  
For more options, visit this group at  
[http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

---

<div class="post-metadata">

**Author:** ![k-b](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/db5fbb/32.png) [@k-b](https://www.ruby-forum.com/u/k-b)\
**Post date:** [December 28, 2009, 2:18am UTC](https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727/3 "2009-12-28T02:18:52Z")

</div>

“What he said” 🙂

Basically it adds an instance method to the ActiveRecord base class,  
which  
in turn lazy-loads the extentions when needed.

I haven’t seen a good in-depth treatise on developing plugins. There is  
some info in Agile Web D. with Rails, and some in The Rails Way  
(Both are excellent books, but I wouldn’t buy either for just this –  
it’s  
too high level)

There is a $9 ebook from peepcode that gives some guidelines for  
building  
different kinds of plugins. Again, it’s not in depth but it provides  
the  
“pattern” to follow to build different kinds of plugins.

I did one recently to generate CSS rounded divs, it was really  
instructional. Generating the CSS and images was easy, figuring out how  
to  
properly extend “stylesheet\_link\_tag” and the generator commands (and in  
fact that I had to do that to get the right behavior) was a fun puzzle  
to  
work out.

Best bet would be to try writing one yourself. You’ll end up reading  
helpful bits on stackoverflow and other places, poking into existing  
plugins  
and eventually learning how some of Rails works internally.

Joe

–

You received this message because you are subscribed to the Google  
Groups “Ruby on Rails: Talk” group.  
To post to this group, send email to removed\_email\_address@domain.invalid.  
To unsubscribe from this group, send email to  
removed\_email\_address@domain.invalid.  
For more options, visit this group at  
[http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

---

<div class="post-metadata">

**Author:** ![k-b](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/db5fbb/32.png) [@k-b](https://www.ruby-forum.com/u/k-b)\
**Post date:** [December 28, 2009, 2:55pm UTC](https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727/4 "2009-12-28T14:55:44Z")

</div>

On Sun, Dec 27, 2009 at 8:16 PM, Joe McGlynn  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> “What he said” 🙂
> 
> Basically it adds an instance method to the ActiveRecord base class, which  
> in turn lazy-loads the extentions when needed.

Actually not exactly. The crucial missing piece is this which comes  
just before the module ClassMethods line:

```
def self.included(base)
    base.extend ClassMethods
 end

```

This overrides the Module#included ‘hook’ method, which gets called  
when another class or module includes Juixe::Acts::Commentable, the  
extend makes methods defined in ClassMethods just that class methods  
of the including class. In this case that’s the acts\_as\_commentable  
method.

That method when called to make a particular subclass of  
ActiveRecord::Base act as commentable

- calls the class method has\_many to ‘declare’ the needed  
association, note that the Rails/ActiveRecord internal dsl statements  
are implemented using the same pattern.
- includes a module which defines the two instance methods  
comments\_ordered\_by\_submitted, and add\_comment
- uses extend to add the find\_comments\_for and find\_comments\_by\_user  
as class methods.

So any subclass of ActiveRecord::Base can use acts\_as\_commentable, and  
those that do get additional instance and class methods, and an  
association.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [Rick DeNatale - Developer - IBM | LinkedIn](http://www.linkedin.com/in/rickdenatale)

–

You received this message because you are subscribed to the Google  
Groups “Ruby on Rails: Talk” group.  
To post to this group, send email to removed\_email\_address@domain.invalid.  
To unsubscribe from this group, send email to  
removed\_email\_address@domain.invalid.  
For more options, visit this group at  
[http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

---

<div class="post-metadata">

**Author:** ![k-b](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/db5fbb/32.png) [@k-b](https://www.ruby-forum.com/u/k-b)\
**Post date:** [December 28, 2009, 4:58pm UTC](https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727/5 "2009-12-28T16:58:06Z")

</div>

> This overrides the Module#included ‘hook’ method, which gets called  
> when another class or module includes Juixe::Acts::Commentable, the  
> extend makes methods defined in ClassMethods just that class methods  
> of the including class. In this case that’s the acts\_as\_commentable  
> method.
> 
> That method when called to make a particular subclass of  
> ActiveRecord::Base act as commentable

Thank you very much! This was more explanation as I hoped to get 🙂

Thanks also everybody else and thanks for the book-advice. This pdf is  
exactly what I am looking for.

–

You received this message because you are subscribed to the Google  
Groups “Ruby on Rails: Talk” group.  
To post to this group, send email to removed\_email\_address@domain.invalid.  
To unsubscribe from this group, send email to  
removed\_email\_address@domain.invalid.  
For more options, visit this group at  
[http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

---

<div class="post-metadata">

**Author:** ![k-b](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/db5fbb/32.png) [@k-b](https://www.ruby-forum.com/u/k-b)\
**Post date:** [December 28, 2009, 2:37pm UTC](https://www.ruby-forum.com/t/difficulties-in-understanding-rail-plugins-in-depth/180727/6 "2009-12-28T14:37:35Z")

</div>

On Sun, Dec 27, 2009 at 8:16 PM, Joe McGlynn  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> “What he said” 🙂
> 
> Basically it adds an instance method to the ActiveRecord base class, which  
> in turn lazy-loads the extentions when needed.
> 
> I haven’t seen a good in-depth treatise on developing plugins. There is  
> some info in Agile Web D. with Rails, and some in The Rails Way  
> (Both are excellent books, but I wouldn’t buy either for just this – it’s  
> too high level)

The techniques used fall into what tends to be called Ruby  
Metaprogramming.

The pragmatic programmers have a series of screen casts by Dave T.  
on this subject as well as a book called Metaprogramming Ruby which is  
either in the late stages of beta or already released.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [Rick DeNatale - Developer - IBM | LinkedIn](http://www.linkedin.com/in/rickdenatale)

–

You received this message because you are subscribed to the Google  
Groups “Ruby on Rails: Talk” group.  
To post to this group, send email to removed\_email\_address@domain.invalid.  
To unsubscribe from this group, send email to  
removed\_email\_address@domain.invalid.  
For more options, visit this group at  
[http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).
