Skip to content

Commit

Permalink
merged from current master
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagopintodev committed Feb 13, 2012
2 parents 65451cf + 56ce55a commit 852b647
Show file tree
Hide file tree
Showing 22 changed files with 146 additions and 102 deletions.
28 changes: 27 additions & 1 deletion Readme.markdown
Expand Up @@ -38,7 +38,7 @@ In summary, you can now:
* [Use your decorators with CanCan](https://github.com/jcasimir/draper/commit/ac1f3083989107d877e2b1c918c3a3e792db99e8)
* [Use a more generalized `options` hash in decorator initialization](https://github.com/jcasimir/draper/commit/03910877d0461356da0968a87346592908f292a7)
* [Get better performance by generating methods](https://github.com/jcasimir/draper/commit/ebe30511b79eac82276413ca7ae54a4a4d86d4dc)
* [Automatically decorate associated objects](https://github.com/jcasimir/draper/commit/1580baa287997ed4e356aae0ffeeb8fe9c326ced)
* [Automatically decorate associated objects](https://github.com/jcasimir/draper/commit/1580baa287997ed4e356aae0ffeeb8fe9c326ced) See Example near bottom of Readme

Thanks to [steveklabnik](http://github.com/steveklabnik), [i0rek](http://github.com/i0rek), [laserlemon](http://github.com/laserlemon), [michaelfairley](http://github.com/michaelfairley), [dnagir](http://github.com/dnagir), [ubermajestix](http://github.com/ubermajestix), [tmaier](http://github.com/tmaier), [angelim](http://github.com/angelim), [duncanbeevers](http://github.com/duncanbeevers), Albert Peng & JR Boyens, [leocassarani](http://github.com/leocassarani), [Jeff Felchner](http://github.com/Felchner), [shingara](http://github.com/shingara), [momolog](http://github.com/momolog), and [ayamomiji](http://github.com/ayamomiji) for their contributions to this version!

Expand Down Expand Up @@ -326,6 +326,32 @@ class ArticleDecorator < ApplicationDecorator
end
end
```

### Example of Decorated Associations

Add a `decorates_association :association_name` to gain access to a decorated version of your target association.

```ruby
class ArticleDecorator < ApplicationDecorator
decorates :article
decorates_association :author # belongs_to :author association
end

class AuthorDecorator < ApplicationDecorator
decorates :author

def fancy_name
"#{model.title}. #{model.first_name} #{model.middle_name[0]}. #{model.last_name}"
end
end
```

Now when you call the association it will use a decorator.

```ruby
<%= @article.author.fancy_name %>
```
## Issues / Pending
* Documentation
Expand Down
4 changes: 2 additions & 2 deletions doc/css/full_list.css
@@ -1,6 +1,6 @@
body {
body {
margin: 0;
font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
font-size: 13px;
height: 101%;
overflow-x: hidden;
Expand Down
60 changes: 30 additions & 30 deletions doc/css/style.css
@@ -1,14 +1,14 @@
body {
body {
padding: 0 20px;
font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
font-size: 13px;
}
body.frames { padding: 0 5px; }
h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; }
h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; }
h1.title { margin-bottom: 10px; }
h1.alphaindex { margin-top: 0; font-size: 22px; }
h2 {
h2 {
padding: 0;
padding-bottom: 3px;
border-bottom: 1px #aaa solid;
Expand All @@ -34,9 +34,9 @@ h2 small { font-weight: normal; font-size: 0.7em; display: block; float: right;
#filecontents dd, .docstring dd { padding: 5px 0px; margin-left: 18px; }
#filecontents dd > p, .docstring dd > p { margin: 0px; }

.note {
.note {
color: #222;
-moz-border-radius: 3px; -webkit-border-radius: 3px;
-moz-border-radius: 3px; -webkit-border-radius: 3px;
background: #e3e4e3; border: 1px solid #d5d5d5; padding: 7px 10px;
display: block;
}
Expand All @@ -47,9 +47,9 @@ h2 small { font-weight: normal; font-size: 0.7em; display: block; float: right;
.note.title { text-transform: lowercase; padding: 1px 5px; font-size: 0.9em; font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; display: inline; }
.summary_signature + .note.title { margin-left: 7px; }
h1 .note.title { font-size: 0.5em; font-weight: normal; padding: 3px 5px; position: relative; top: -3px; text-transform: capitalize; }
.note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; }
.note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; }
.note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; }
.note.title.constructor { color: #fff; background: #6a98d6; border-color: #6689d6; }
.note.title.writeonly { color: #fff; background: #45a638; border-color: #2da31d; }
.note.title.readonly { color: #fff; background: #6a98d6; border-color: #6689d6; }
.note.title.private { background: #d5d5d5; border-color: #c5c5c5; }
.discussion .note { margin-top: 6px; }
.discussion .note:first-child { margin-top: 0; }
Expand Down Expand Up @@ -123,9 +123,9 @@ dl.constants .discussion *:last-child { margin-bottom: 0; }

.method_details { border-top: 1px dotted #aaa; margin-top: 15px; padding-top: 0; }
.method_details.first { border: 0; }
p.signature {
font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace;
padding: 6px 10px; margin-top: 18px;
p.signature {
font-size: 1.1em; font-weight: normal; font-family: Monaco, Consolas, Courier, monospace;
padding: 6px 10px; margin-top: 18px;
background: #e5e8ff; border: 1px solid #d8d8e5; -moz-border-radius: 3px; -webkit-border-radius: 3px;
}
p.signature tt { font-family: Monaco, Consolas, Courier, monospace; }
Expand All @@ -145,7 +145,7 @@ p.signature .aliases .names { font-family: Monaco, Consolas, Courier, monospace;
.tags .examples h4 { padding: 0; margin: 0; margin-left: 15px; font-weight: bold; font-size: 0.9em; }

.tags .overload .overload_item { list-style: none; margin-bottom: 25px; }
.tags .overload .overload_item .signature {
.tags .overload .overload_item .signature {
padding: 2px 8px;
background: #e5e8ff; border: 1px solid #d8d8e5; -moz-border-radius: 3px; -webkit-border-radius: 3px;
}
Expand All @@ -169,19 +169,19 @@ ul.summary {
font-size: 1em;
line-height: 1.5em;
}
ul.summary a:link, ul.summary a:visited {
ul.summary a:link, ul.summary a:visited {
text-decoration: none; font-size: 1.1em;
}
ul.summary li { margin-bottom: 5px; }
.summary .summary_signature {
.summary .summary_signature {
padding: 1px 10px;
background: #eaeaff; border: 1px solid #dfdfe5;
-moz-border-radius: 3px; -webkit-border-radius: 3px;
-moz-border-radius: 3px; -webkit-border-radius: 3px;
}
.summary_signature:hover { background: #eeeeff; cursor: pointer; }
ul.summary.compact li { display: inline-block; margin: 0px 5px 0px 0px; line-height: 2.6em;}
ul.summary.compact .summary_signature { padding: 5px 7px; padding-right: 4px; }
#content .summary_signature:hover a:link,
#content .summary_signature:hover a:link,
#content .summary_signature:hover a:visited {
background: transparent;
color: #48f;
Expand All @@ -204,18 +204,18 @@ ul.fullTree li:last-child { padding-bottom: 0; }
.showAll .inheritName { display: none; }

#search { position: absolute; right: 14px; top: 0px; }
#search a:link, #search a:visited {
#search a:link, #search a:visited {
display: block; float: left; margin-right: 4px;
padding: 8px 10px; text-decoration: none; color: #05a;
border: 1px solid #d8d8e5;
-moz-border-radius-bottomleft: 3px; -moz-border-radius-bottomright: 3px;
-moz-border-radius-bottomleft: 3px; -moz-border-radius-bottomright: 3px;
-webkit-border-bottom-left-radius: 3px; -webkit-border-bottom-right-radius: 3px;
background: #eaf0ff;
-webkit-box-shadow: -1px 1px 3px #ddd;
}
#search a:hover { background: #f5faff; color: #06b; }
#search a.active {
background: #568; padding-bottom: 20px; color: #fff; border: 1px solid #457;
#search a.active {
background: #568; padding-bottom: 20px; color: #fff; border: 1px solid #457;
-moz-border-radius-topleft: 5px; -moz-border-radius-topright: 5px;
-webkit-border-top-left-radius: 5px; -webkit-border-top-right-radius: 5px;
}
Expand Down Expand Up @@ -249,8 +249,8 @@ li.r2 { background: #fafafa; }
z-index: 9999;
background: #fff;
display: none;
position: absolute;
top: 36px;
position: absolute;
top: 36px;
right: 18px;
width: 500px;
height: 80%;
Expand All @@ -266,7 +266,7 @@ li.r2 { background: #fafafa; }
#content ul.summary li.deprecated .summary_signature a:link,
#content ul.summary li.deprecated .summary_signature a:visited { text-decoration: line-through; font-style: italic; }

#toc {
#toc {
padding: 20px; padding-right: 30px; border: 1px solid #ddd; float: right; background: #fff; margin-left: 20px; margin-bottom: 20px;
max-width: 300px;
-webkit-box-shadow: -2px 2px 6px #bbb;
Expand All @@ -291,7 +291,7 @@ li.r2 { background: #fafafa; }
#filecontents pre.code, .docstring pre.code, .source_code pre { font-family: monospace; }
#filecontents pre.code, .docstring pre.code { display: block; }
.source_code .lines { padding-right: 12px; color: #555; text-align: right; }
#filecontents pre.code, .docstring pre.code,
#filecontents pre.code, .docstring pre.code,
.tags .example { padding: 5px 12px; margin-top: 4px; border: 1px solid #eef; background: #f5f5ff; }
pre.code { color: #000; }
pre.code .info.file { color: #555; }
Expand All @@ -300,21 +300,21 @@ pre.code .tstring_content,
pre.code .heredoc_beg, pre.code .heredoc_end,
pre.code .qwords_beg, pre.code .qwords_end,
pre.code .tstring, pre.code .dstring { color: #036A07; }
pre.code .fid, pre.code .id.new, pre.code .id.to_s,
pre.code .id.to_sym, pre.code .id.to_f,
pre.code .fid, pre.code .id.new, pre.code .id.to_s,
pre.code .id.to_sym, pre.code .id.to_f,
pre.code .dot + pre.code .id,
pre.code .id.to_i pre.code .id.each { color: #0085FF; }
pre.code .comment { color: #0066FF; }
pre.code .const, pre.code .constant { color: #585CF6; }
pre.code .symbol { color: #C5060B; }
pre.code .kw,
pre.code .kw,
pre.code .label,
pre.code .id.require,
pre.code .id.require,
pre.code .id.extend,
pre.code .id.include { color: #0000FF; }
pre.code .ivar { color: #318495; }
pre.code .gvar,
pre.code .id.backref,
pre.code .gvar,
pre.code .id.backref,
pre.code .id.nth_ref { color: #6D79DE; }
pre.code .regexp, .dregexp { color: #036A07; }
pre.code a { border-bottom: 1px dotted #bbf; }
20 changes: 10 additions & 10 deletions doc/js/app.js
Expand Up @@ -44,7 +44,7 @@ function createFullTreeLinks() {

function fixBoxInfoHeights() {
$('dl.box dd.r1, dl.box dd.r2').each(function() {
$(this).prev().height($(this).height());
$(this).prev().height($(this).height());
});
}

Expand Down Expand Up @@ -113,7 +113,7 @@ function summaryToggle() {
if (next.hasClass('compact')) {
next.toggle();
next.next().toggle();
}
}
else if (next.hasClass('summary')) {
var list = $('<ul class="summary compact" />');
list.html(next.html());
Expand Down Expand Up @@ -159,13 +159,13 @@ function generateTOC() {
if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; }
this.id = proposedId;
}
if (thisTag > lastTag) {
for (i = 0; i < thisTag - lastTag; i++) {
var tmp = $('<ol/>'); toc.append(tmp); toc = tmp;
}
if (thisTag > lastTag) {
for (i = 0; i < thisTag - lastTag; i++) {
var tmp = $('<ol/>'); toc.append(tmp); toc = tmp;
}
}
if (thisTag < lastTag) {
for (i = 0; i < lastTag - thisTag; i++) toc = toc.parent();
if (thisTag < lastTag) {
for (i = 0; i < lastTag - thisTag; i++) toc = toc.parent();
}
toc.append('<li><a href="#' + this.id + '">' + $(this).text() + '</a></li>');
lastTag = thisTag;
Expand All @@ -174,7 +174,7 @@ function generateTOC() {
html = '<div id="toc"><p class="title"><a class="hide_toc" href="#"><strong>Table of Contents</strong></a> <small>(<a href="#" class="float_toc">left</a>)</small></p></div>';
$('#content').prepend(html);
$('#toc').append(_toc);
$('#toc .hide_toc').toggle(function() {
$('#toc .hide_toc').toggle(function() {
$('#toc .top').slideUp('fast');
$('#toc').toggleClass('hidden');
$('#toc .title small').toggle();
Expand All @@ -183,7 +183,7 @@ function generateTOC() {
$('#toc').toggleClass('hidden');
$('#toc .title small').toggle();
});
$('#toc .float_toc').toggle(function() {
$('#toc .float_toc').toggle(function() {
$(this).text('float');
$('#toc').toggleClass('nofloat');
}, function() {
Expand Down
16 changes: 8 additions & 8 deletions doc/js/full_list.js
Expand Up @@ -10,17 +10,17 @@ function fullListSearch() {
var link = $(this).find('.object_link a');
searchCache.push({name:link.text(), node:$(this), link:link});
});

$('#search input').keyup(function() {
searchString = this.value.toLowerCase();
if (searchString === "") {
clearTimeout(inSearch);
inSearch = null;
$('#full_list, #content').removeClass('insearch');
$('#full_list li').removeClass('found').each(function() {

var link = $(this).find('.object_link a');
link.text(link.text());
link.text(link.text());
});
if (clicked) {
clicked.parents('ul').each(function() {
Expand All @@ -38,7 +38,7 @@ function fullListSearch() {
searchItem();
}
});

$('#search input').focus();
$('#full_list').after("<div id='noresults'></div>");
}
Expand All @@ -54,8 +54,8 @@ function searchItem() {
item.node.css('padding-left', '10px').addClass('found');
item.node.removeClass(lastRowClass).addClass(lastRowClass == 'r1' ? 'r2' : 'r1');
lastRowClass = item.node.hasClass('r1') ? 'r1' : 'r2';
item.link.html(item.name.replace(new RegExp("(" +
searchString.replace(/([\/.*+?|()\[\]{}\\])/g, "\\$1") + ")", "ig"),
item.link.html(item.name.replace(new RegExp("(" +
searchString.replace(/([\/.*+?|()\[\]{}\\])/g, "\\$1") + ")", "ig"),
'<strong>$1</strong>'));
}

Expand Down Expand Up @@ -110,10 +110,10 @@ function linkList() {

function collapse() {
if (!$('#full_list').hasClass('class')) return;
$('#full_list.class a.toggle').click(function() {
$('#full_list.class a.toggle').click(function() {
$(this).parent().toggleClass('collapsed').next().toggleClass('collapsed');
highlight();
return false;
return false;
});
$('#full_list.class ul').each(function() {
$(this).addClass('collapsed').prev().addClass('collapsed');
Expand Down
8 changes: 5 additions & 3 deletions lib/draper/base.rb
Expand Up @@ -5,13 +5,15 @@ class Base
attr_accessor :model, :options

DEFAULT_DENIED = Object.new.methods << :method_missing
DEFAULT_ALLOWED = []
FORCED_PROXY = [:to_param, :id]
FORCED_PROXY.each do |method|
define_method method do |*args, &block|
model.send method, *args, &block
end
end
self.denied = DEFAULT_DENIED
self.allowed = DEFAULT_ALLOWED

# Initialize a new decorator instance by passing in
# an instance of the source class. Pass in an optional
Expand Down Expand Up @@ -89,7 +91,7 @@ def self.decorates_associations(*association_symbols)
# @param [Symbols*] methods to deny like `:find, :find_by_name`
def self.denies(*input_denied)
raise ArgumentError, "Specify at least one method (as a symbol) to exclude when using denies" if input_denied.empty?
raise ArgumentError, "Use either 'allows' or 'denies', but not both." if self.allowed?
raise ArgumentError, "Use either 'allows' or 'denies', but not both." unless (self.allowed == DEFAULT_ALLOWED)
self.denied += input_denied
end

Expand All @@ -105,7 +107,7 @@ def self.denies(*input_denied)
def self.allows(*input_allows)
raise ArgumentError, "Specify at least one method (as a symbol) to allow when using allows" if input_allows.empty?
raise ArgumentError, "Use either 'allows' or 'denies', but not both." unless (self.denied == DEFAULT_DENIED)
self.allowed = input_allows
self.allowed += input_allows
end

# Initialize a new decorator instance by passing in
Expand Down Expand Up @@ -235,7 +237,7 @@ def source
private

def allow?(method)
(!allowed? || allowed.include?(method) || FORCED_PROXY.include?(method)) && !denied.include?(method)
(allowed.empty? || allowed.include?(method) || FORCED_PROXY.include?(method)) && !denied.include?(method)
end
end
end
2 changes: 1 addition & 1 deletion lib/draper/decorated_enumerable_proxy.rb
Expand Up @@ -21,7 +21,7 @@ def method_missing (method, *args, &block)
def respond_to?(method)
super || @wrapped_collection.respond_to?(method)
end

def kind_of?(klass)
super || @wrapped_collection.kind_of?(klass)
end
Expand Down

0 comments on commit 852b647

Please sign in to comment.