comfy/comfortable-mexican-sofa — pull request #409 by Emerson (2014-02-07 07:41:26+00:00)
Title: Introducing: cms_acts_as_cms

![cms_acts_as_cms](http://i.imgur.com/4B8qhBo.png)

#### Have you ever been working on a project and wanted to treat one of your existing models just like a Cms::Page object?

At first this might sound bizarre, but I assure you, the use case is real, awesome, and actually has minimal impact on the comfy codebase. Let's take a moment to think this through....

Anyone who knows Comfy understands that its real benefit comes from layouts, tags, and blocks. Writing a layout that generates a dynamic form is a _huge time saver_ and there have been a number of occasions where I've wanted the magic of Comfy mixed into my boring old Rails models. So with this in mind, I'd like to introduce **cms_acts_as_cms**.

#### What Does It Do?

Let's start with a boring old rails model:

```ruby
class BoringModel < ActiveRecord::Base

validates :is_boring, presence: true

end
```

So hey, let's spice things up by adding in the `cms_acts_as_cms` behaviour _(I know the name is a little terse, but it fits with the existing extensions)_. The only requirements are that we provide a `layout` method that returns a proper Comfy layout and add a `content` column on the model. Once you've done this, the benefits are clear:

```ruby

class BoringModel < ActiveRecord::Base

validates :is_awesome, presence: true

cms_acts_as_cms

# Your job to figure out a nice way to handle this...
def layout
Cms::Layout.new(content: "

{{ cms:page:random_content }}

")
end

end

# Let's assume we have an instance of our BoringModel
boring_model = BoringModel.first
# Set some blocks that match the layout we defined in the class...
boring_model.blocks_attributes = [{ :identifier => 'random_content', :content => 'not so boring anymore ;-)' }]

boring_model.render
#=> "

not so boring anymore ;-)

"
```

_c'est bon, non?_

### But Why?

The possibilities are endless. Blocks. Layouts. Revisions. Rendering. Form Builders. Etc...

### But How?

`Cms::Blocks` are now polymorphic. **Mind == Blown**.

### What About Forms?

Ahhh, yes. Let's use some of those sweet sweet Comfy forms. Obviously the context of this code is within your admin area:

```haml
.row-fluid
.span12
.page-header
= comfy_form_for @awesome_model do |form|
= form.text_field :title
= form.text_area :normal_boring_stuff
/ Bring the awesome...
/ renders the Comfy form builder and handles any blocks you have...
/ it's an engine, so just override it if you need anything special
= render partial: 'admin/cms/pages/form_blocks', locals: {cms_object: form.object}
```