Make all models that are going to be used by that template respond to
the same message. If at your template, you're calling "item.title",
all models that are going to be used in there should have a "title"
method. In your case, you can just alias the "name" method to "title".
A better approach would be to implement the "to_s" method in your
active record models by returning these "name" properties.
If you have a user model, you could implement it's to_s like the following:
class User < ActiveRecord::Base
def to_s
login
end
end
So you don't even care about what that model is, you just expect it's
to_s method to yield a correct "label".
> And since this markup will be similar to the
> front-end display (non-admin), is there a good way to set the link_to
> to be either :admin or :root?
You can just add another parameter at the render :partial call.
> I'm working on fixing up the code in my first Rails application and
> have come around to DRYing up the views and partials. For the most
> part, I'm satisfied with the DRYness of the application, but I have
> 5-6 partials that display nearly identical XHTML, just with different
> content, link_to paths, and images.
This supplements your other answers, which are doubtless technically correct.
The DRY is primarily about the behaviors of methods in an OO design. Having two
methods that do the exact same thing, but with different labels or a different
algorithm, is the greatest violation of DRY. (Start by seeing if you can make
the two methods look more similar, before merging them. If you can't, at least
find a way to put them right next to each other!)
Similarly, your metadata should be DRY. This is why (and how) Rails obeys
"convention before configuration". Don't write an XML file saying "our unit
tests are in the test/ folder". That repeats the information stored in the name
of the folder.
Now we come to the heart of the matter. HTML, by itself, is not behavior, and
it's almost not structure. It is mostly art. DRYing two similar stretches of
HTML is the moral equivalent of DRYing all your #fff and "white" CSS directives.
It's okay if they say the same thing, when they don't use logical statements to
say them, and when you might not frequently need to change them all at the same
time.
So that is the answer to "too DRY". Keep DRYing your project until you reach a
local maximum of convenience, and then don't DRY any more.
--
Phlip
>
> I'm working on fixing up the code in my first Rails application and
> have come around to DRYing up the views and partials. For the most
> part, I'm satisfied with the DRYness of the application, but I have
> 5-6 partials that display nearly identical XHTML, just with different
> content, link_to paths, and images.
>
> I know this question is entirely subjective, but would finding a way
> to further DRY the 5-6 partials into one partial with plugs for
> different fillers be too much? If so, how would I go about doing
> this?
My criteria for *repeat* detection is, what you want when you need
to change them. When you DRY up two similar parts, you lose the ability
to modify one without affect the other one. So I think if the similar
parts are likely to change in the same way in future, they should be
DRYed; otherwise I prefer to keep them seperate although they looks
simliar to each other.
my $0.02
Jan
>
> 2 examples...
>
> http://pastie.org/402754
> http://pastie.org/402756
> --~--~---------~--~----~------------~-------~--~----~
> 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 rubyonra...@googlegroups.com
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
> -~----------~----~----~----~------~----~------~--~---
--
jan=callcc{|jan|jan};jan.call(jan)
First it's for the sake of consistency, but it's also 'cos the to_s
method is defined to return a "string representation of the object",
so if you already have a method that does what you want, why create
another one or why care about creating another method that "returns a
string representation of the object"?
This way you don't need to add extra virtual methods at your models,
you just expect them to have a good to_s implementation.
> Thanks. This has been really helpful. I used your example to create
> the following. Thoughts?
>
> http://pastie.org/402843
It's good, but that's how I'd do it -> http://pastie.org/403009
The more conventions you have, the easier it is to keep things
consistent in your pages.
Usually, you shouldn't need it unless what you need is a "string
representation of your object" (yes, i'm sounding like a broken vinyl
now ;D), and receiving a user_name or a title would probably be what
you're looking for.
Also, if it's something for debugging purposes in Ruby we use "inspect".
> Plus, wouldn't I be writing more code given that every model must now have a
> custom defined to_s method? Unless adding extra virtual attributes is
> bad, would it be less work (given that I'd have to change two models
> at this point) to just add a "title" method for those that doesn't
> respond to title?
>
Yes and no. When you say that it's "title", it has to be a method
called title, so you're stuck with this "title" thing, if a model has
a title and you don't want to use it, you're about to have a problem.
Using to_s or a to_label (this one feels clumsy) means your view code
don't need to know which method is going to be called, which
simplifies changes in the future. Imagine that today, when presenting
a user, you show it's full name, but later on there's a request to,
instead of showing the full name, show only the login, if you had a
full_name call at every user show, you'd have to change them all to
login, but if you had oveeriden the to_s method you would just have to
change it in one place.
Also, when you override the to_s method you don't need to call it at
the view, as you need to call the "title" method:
<%= link_to user, user %>
The link_to helper will automatically call "to_s" at your object, so
you don't have to call it by yourself.