Noob learning DRY

I am very new to RoR (this is my second day). I have started my first
application, and want to follow best practices as much as possible. I
created a select box that lists all the items in a table column on a
new.html.erb page. I then realized I needed to create one on the edit
page. I want to use this select box on several other pages as well.

Trying to keep with D.R.Y. I am wondering if there is a better way to
do this, instead of putting this statement on every page.

<%= select("note", "project_id", Project.find(:all).collect {|p|
[p.name, p.id]}) %>

Hi Greg,

I am very new to RoR (this is my second day).

Welcome!

I have started my first
application, and want to follow best practices as much as possible. I
created a select box that lists all the items in a table column on a
new.html.erb page. I then realized I needed to create one on the edit
page. I want to use this select box on several other pages as well.

Trying to keep with D.R.Y. I am wondering if there is a better way to
do this, instead of putting this statement on every page.

<%= select("note", "project_id", Project.find(:all).collect {|p|
[p.name, p.id]}) %>

Short answer... maybe. You could refactor it into a partial but a
one-liner partial usually doesn't make much sense. One part of the DRY
rationale is about minimizing lines of code in the code base. That's
goodness, but with one-liners you're actually increasing the number of
lines of code by one and the size question always needs to be balanced
against the performance hit of initializing another class. Don't get
too anal with DRY. Opinions vary but, IMO, the real value of DRY is to
minimize the number of places you have to go to make changes. So, if
you think this select is likely to be used in a lot of places and is
likely to change, then you should consider moving it to a partial more
strongly than if it's not likely to change.

HTH,
Bill

Hi,

Have a look at partials. That's where you can call the same snippet of
render code from several views. Also, best practice seems to indicate you
should put the find in the controller, not in the view.

Cheers
Simon

Thanks guys. I will look more into partials and also try to move my
find into the controller. I appreciate the help!

Thanks guys. I will look more into partials and also try to move my

find into the controller. I appreciate the help!

Hi,

Have a look at partials. That’s where you can call the same snippet of

render code from several views. Also, best practice seems to indicate you

should put the find in the controller, not in the view.

Cheers

Simon

I am very new to RoR (this is my second day). I have started my first

application, and want to follow best practices as much as possible. I

created a select box that lists all the items in a table column on a

new.html.erb page. I then realized I needed to create one on the edit

page. I want to use this select box on several other pages as well.

Trying to keep with D.R.Y. I am wondering if there is a better way to

do this, instead of putting this statement on every page.

<%= select(“note”, “project_id”, Project.find(:all).collect {|p|

[p.name, p.id]}) %>

Hi, I would recommend using the guides at the following location:

http://guides.rails.info

Good luck,

-Conrad

There are a few core practices you can follow with view templates and
attempting a DRY concept.

Partials are fine if you have a lot of repeating HTML in many of your
views because you can use a partial for table structures etc. As an
example, if you are creating a large table and that table needs to be
used in several views within the same controller, you can use a partial
for the other views.

However, when working with actual code, I like to work with helpers.
The best practice is not to include too much code functionality in your
views but move those to a helper if you find yourself needing the same
one over and over.

You should follow these basic things:

Views are meant for html and all things that represent the display your
users see. Your controllers are the director that talks to your models
and to your views. When you need a database call, the controller talks
to the model and the model retrieves the data and hands it back to the
controller, who then hands it back to the view.

Don't make the mistake of trying to skip the MVC architecture in your
project. If you form bad habits they are hard to break.

I think the only thing I would change from the code is to place
Project.find(:all).collect {|p| [p.name, p.id]}) in Project model

def self.to_options
    find(:all).map { |p| [p.name, r.id] }.unshift(['Choose a
project:', ''])
end

So then I'll just use it like this

<%= select("note", "project_id", Project.to_options) %>

So you don't have meaningless helper, it still DRY and still follows
MVC

Cheers!
Arzumy

I tend to agree with this - one-liners typically go into helpers in my
code, while anything longer is factored out into a partial. It can
also be helpful to have a helper which crunches some parameters and
then calls a partial. But that style is partly driven by writing a lot
of DRYML...

As for the suggestions for to_options - that can be useful sometimes,
but it's getting (IMHO) dangerously close to sticking controller/view
code in the model (especially the prompt text). Now, if you want to
only have *some* of the models on the menu (ie, you're doing Model.find
(conditions).map ...) then the first bit of that definitely belongs in
the model.

--Matt Jones

I tend to agree with this - one-liners typically go into helpers in my
code, while anything longer is factored out into a partial. It can
also be helpful to have a helper which crunches some parameters and
then calls a partial. But that style is partly driven by writing a lot
of DRYML...

As for the suggestions for to_options - that can be useful sometimes,
but it's getting (IMHO) dangerously close to sticking controller/view
code in the model (especially the prompt text).

I disagree here, I would contend that there is nothing wrong with have
a model method which performs the action "Get a set of valid options".
_How_ to display it - as a select box, checkboxes, etc and how it is
formatted is up to the view, but the model should decide which options
are provided. I also think it is ok to call this from the view in
this situation rather than from the controller to pass to the view.
The controller does not need to know that the view wants to display a
list for the user to select from.

Colin