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