# Help with DRY: too much code in my view

**URL:** <https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319>\
**Category:** Rails\
**Created:** [February 26, 2006, 12:11am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319 "2006-02-26T00:11:30Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 12:11am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/1 "2006-02-26T00:11:30Z")

</div>

I’m a newbie to rails, and really to the whole DRY and MVC thing as  
well, except where I accidentally fell into things doing it my own way  
in the past.

I’ve got a fairly complex DB structure I want to create an interface for  
using Rails. Getting simple tables to display, edit, save, not too much  
problem there. But where I’m having trouble is figuring out where to  
place some code I have had to write to get info from multiple tables  
into one view. For example, for a list view of “projects” (main table),  
I have this code in the list.rhtml:

```
<%
odd_or_even = 0
for project in @projects
	@project_translations = ProjectTranslation.find(project.id)
 	@business_unit = BusinessUnit.find(project.business_unit_id)
	@requestor = User.find(project.requester_user_id)
	@vendor_projects = 

```

VendorProject.find\_by\_project\_translation\_id(@project\_translations.id)  
@vendor = Vendor.find(@vendor\_projects.vendor\_id)  
odd\_or\_even = 1 - odd\_or\_even  
%\>

This code I would probably need in other views as well. For the list  
that customers see, for individual record views, etc. The question is:  
where _should_ I be putting that code? In the controller? In the model?  
and how, exactly?

I have another question semi-related to this about how ids work and why  
I have to do find all the time, but I’ll post that in a different  
thread.

Micah

---

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 12:46am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/2 "2006-02-26T00:46:16Z")

</div>

On Feb 25, 2006, at 3:11 PM, Micah B. wrote:

> \<%
> 
> This code I would probably need in other views as well. For the list  
> that customers see, for individual record views, etc. The question is:  
> where _should_ I be putting that code? In the controller? In the  
> model?  
> and how, exactly?

You’re not using associations, and you’re not following naming  
conventions.

Once you get everything together, you’ll be able to say things like:

project.project\_tranlations  
project.business\_unit  
project.requestor  
project.project\_tranlations.vendor\_projects  
project.project\_tranlations.vendor\_projects.vendor

–  
– Tom M.

---

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 12:52am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/3 "2006-02-26T00:52:21Z")

</div>

Micah,

1/ replace “odd\_or\_even” by TextHelper.cycle

2/ It looks like your model could be enriched, to have Rails do the hard  
work or finding related records. In other words, remove all the "find"s  
in your views by adding “has\_one”, “has\_many” and “belongs\_to” in your  
models.  
(Tip: when you see “belongs\_to :x”, think “references :x”, or “points\_to  
:x”)

Example: if you add

```
class Project < ActiveRecord::Base
    has_one :translation
end
class Translation < ActiveRecord::Base
    belongs_to :project
end

```

this code  
@project\_translation = ProjectTranslation.find(project.id)

would become  
@project\_translation = project.translation

3/ I’m puzzled by code like this  
@project\_translations = ProjectTranslation.find(project.id)

- Why the plural on the left side, whey you’re obviously fetching 1  
record?
- How come the project and the translation share the same id? Normally,  
you don’t handle ids explicitely (? is this a legacy project/db)?

Alain

---

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 3:35am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/4 "2006-02-26T03:35:28Z")

</div>

Alain R. wrote:

> Micah,
> 
> 1/ replace “odd\_or\_even” by TextHelper.cycle

Sadly, I don’t even know what that is. I’ll do some digging, thanks for  
the hint!

> 2/ It looks like your model could be enriched, to have Rails do the hard  
> work or finding related records. In other words, remove all the "find"s  
> in your views by adding “has\_one”, “has\_many” and “belongs\_to” in your  
> models.  
> (Tip: when you see “belongs\_to :x”, think “references :x”, or “points\_to  
> :x”)
> 
> Example: if you add
> 
> ```
> class Project < ActiveRecord::Base
> has_one :translation
> end
> class Translation < ActiveRecord::Base
> belongs_to :project
> end
> 
> ```
> 
> this code  
> @project\_translation = ProjectTranslation.find(project.id)
> 
> would become  
> @project\_translation = project.translation

hmm. That’s what _I_ thought it should be doing too… (see above  
reply).

> 3/ I’m puzzled by code like this  
> @project\_translations = ProjectTranslation.find(project.id)
> 
> - Why the plural on the left side, whey you’re obviously fetching 1  
> record?

Well, this isn’t complete yet. The reason is that there can be 1+  
project\_translations for any project. Or if you named it differently, a  
“project” has one source language, and n number of target languages,  
each of which could be done by a separate vendor, have separate  
leveraging, cost, deadlines, etc.

> - How come the project and the translation share the same id? Normally,  
> you don’t handle ids explicitely (? is this a legacy project/db)?

This is a test set of data (a migration from existing data source), and  
each project in this test set only has one target language, so when the  
insert happened, the projects and project\_translations ids ended up  
being 1:1. That won’t be the case in production.

I think I’ll revert a few versions back and see what error messages I  
was getting and try to sort out what’s going wrong with my models. I  
was getting frustrated and wanted to make it show me SOMETHING.

Thanks help,

Micah

---

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 3:28am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/5 "2006-02-26T03:28:08Z")

</div>

Tom M. wrote:

> You’re not using associations, and you’re not following naming  
> conventions.
> 
> Once you get everything together, you’ll be able to say things like:
> 
> project.project\_tranlations  
> project.business\_unit  
> project.requestor  
> project.project\_tranlations.vendor\_projects  
> project.project\_tranlations.vendor\_projects.vendor

Well, that’s what I thought I should be able to, it’s what I was going  
to make the other post about. I _think_ I’ve followed the db naming  
conventions pretty closely… Everything has an ‘id’ field that’s an  
int, foreign key fields are named with the table name + “\_id”. I also  
set up in the models, all the has\_one, has\_many, belongs\_to, etc.  
things.

I should have said that I did try the above reference style, but got  
error messages. I’ll revert a few versions and check out exactly what  
those errors were.

Micah

---

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 3:39am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/6 "2006-02-26T03:39:08Z")

</div>

On 2/25/06, Micah B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Alain R. wrote:
> 
> > Micah,
> > 
> > 1/ replace “odd\_or\_even” by TextHelper.cycle
> 
> Sadly, I don’t even know what that is. I’ll do some digging, thanks for  
> the hint!

hint #2 🙂  
[http://api.rubyonrails.com/classes/ActionView/Helpers/TextHelper.html#M000430](http://api.rubyonrails.com/classes/ActionView/Helpers/TextHelper.html#M000430)

---

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 4:59am UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/7 "2006-02-26T04:59:38Z")

</div>

Pat M. wrote:

> hint #2 🙂  
> [Peak Obsession](http://api.rubyonrails.com/classes/ActionView/Helpers/TextHelper.html#M000430)

Alain and Pat,

Thanks for that one, it works like a charm!

* * *

Ok, I did some reverting, and these are the types of errors I get:

undefined method `vendor\_projects’ for ProjectTranslation:Class  
32: vendor\_projects = project.project\_translations.vendor\_projects

and if I go back to manually finding for vendor\_projects there, just to  
get past that, I get this nil error from the vendor\_projects.vendor\_id:

You have a nil object when you didn’t expect it!  
The error occured while evaluating nil.vendor\_id  
35: vendor = Vendor.find(vendor\_projects.vendor\_id)

If I did everything the way I _think_ I should be doing it, I’d have  
something like this:  
for project in @projects  
project\_translations = project.project\_translations  
bu\_name = project.business\_unit.name  
requester = User.find(project.requester\_user\_id)  
# ^ still haven’t solved this one because i don’t use “user\_id” as the  
field name here (I have 3 users referenced in this table)  
vendor\_projects = project.project\_translations.vendor\_projects  
vendor = vendor\_projects.vendor

But that doesn’t work for me yet. If you’re still reading, here’s how I  
have the Classes set up:

class Project \< ActiveRecord::Base  
has\_many :project\_translations  
has\_many :users  
has\_one :language

class ProjectTranslation \< ActiveRecord::Base  
belongs\_to :project  
has\_one :language  
has\_many :vendor\_projects

class User \< ActiveRecord::Base  
belongs\_to :project  
belongs\_to :project\_translation

class Vendor \< ActiveRecord::Base  
belongs\_to :vendor\_projects

class VendorProject \< ActiveRecord::Base  
belongs\_to :project\_translations  
has\_many :vendor\_invoices  
has\_many :vendor\_scope\_changes  
has\_one :vendor

I’m not sure I have the Project\>has\_many :users thing right… it’s  
really 3 relationships, but all are has\_one relationships. (3 fields,  
can only be 1 users for each of them).

---

<div class="post-metadata">

**Author:** ![yak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/b3f665/32.png) [@yak](https://www.ruby-forum.com/u/yak)\
**Post date:** [February 26, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/help-with-dry-too-much-code-in-my-view/73319/8 "2006-02-26T21:13:18Z")

</div>

Just wanted to thank everyone for the suggestions. I did get the above  
mess cleaned up and working in what I hope is a more Railed manner. In  
my view, I now have just this:  
for project in @projects  
project\_hash = project.list\_hash

list\_hash is a method in the Project class that gets the data I need  
from the various tables, does some calculations, sum(), avg(), etc, and  
returns it in a hash that the view can use, as here:

 \<%= number\_to\_currency(project\_hash["vendor\_estimate"]) %\>

I made an effort to keep anything that formatted a number, out of the  
Project class, and into the view helpers. I believe that’s the right  
Rails thing to do.

Except for 3 connection.select\_value() calls to get avg and sum, there’s  
no more sql in the method at all, no find\_by…

Micah
