DRY - in controller or model?

Hello.

I’m trying to make clean efficient code and would like to find out if
there is a “BEST” way to write code. I want this to run quickly and
efficiently for my app.

I’ve got a form that needs a select list created for new and edit
functions. Same list.

Do I do this in the controller and reference @list in the forms?

def new
@list = %w { apple orange banana }
end

def edit
@list = %w { apple orange banana }
end

Or do I put this in the model and just reference model.list in the
forms?

def list
%w { apple orange banana }
end

Or is there a better way?

Thanks!

I’d do a before filter (in controller)

before_filter :populate_list, :only => [:new, :edit]

def populate_list
@list = %w(…)
end

Jason

On Fri, Feb 22, 2008 at 4:16 PM, Becca G.

Becca G. wrote:

Or is there a better way?

Thanks!

Models should contain functionality to expose and manipulate their state
and nothing more. If an actual model contains the attributes that you
listed above then it’s find to ask the model for a list from the
controller.

Controllers are solely responsible for mapping views to models. Their
functionality should be focussed around this task. If a controller
doesn’t need to have access to a model’s state (which is the preferred
way) then it shouldn’t.

Lastly, a model should never have ANY knowledge of it’s business context
within the application. It should be completely application agnostic.

hth

ilan

Ilan B. wrote:
If an actual model contains the attributes that you

listed above then it’s find to ask the model for a list from the
controller.

Thanks for the replies.

Just for clarification, if, for example, my order form is in the grocery
model and the items in the list are part of a produce model, then it’s
not good practice to ask the grocery model to find the list of produce,
correct?

Becca G. wrote:

Ilan B. wrote:
If an actual model contains the attributes that you

listed above then it’s find to ask the model for a list from the
controller.

Thanks for the replies.

Just for clarification, if, for example, my order form is in the grocery
model and the items in the list are part of a produce model, then it’s
not good practice to ask the grocery model to find the list of produce,
correct?

If there is an association (one to many, many to many) between grocery
and produce then it’s perfectly ok to ask the grocery model for it’s
list of produce. In fact this is exactly how “has_many()” works!

class Produce
belongs_to :grocery
end

class Grocery
has_many :produces
end

Grocery.new.produces

[]

hth

ilan

Ilan B. wrote:

class Produce
belongs_to :grocery
end

class Grocery
has_many :produces
end

Grocery.new.produces

[]

I understand the concept and “think” that I almost have it. I do have my
model relationship as you noted.

I have a belongs_to relationship and I have a def for the produce_list
which then I think duplicates rails functionality.

So if I’m populating a select list, what would the select statement look
like, i.e, how do I reference the produce list?

Currently I have something like this:
<%= f.select :produce_id, Order.produce_list %>

Here’s what I had when I started asking the question and now after
reading the posts, I’m wondering if it’s correct or what needs to
change. The controller does not have any related code. Here’s the
model and view.

model:
class Order < ActiveRecord::Base
belongs_to :customer

def self.customer_list
Customer.find(:all).collect{|c| [c.name, c.id]}
end
end

view:
<%= f.select :customer_id, Order.customer_list %>

Thanks.

Becca G. wrote:

I understand the concept and “think” that I almost have it. I do have my
model relationship as you noted.

I have a belongs_to relationship and I have a def for the produce_list
which then I think duplicates rails functionality.

So if I’m populating a select list, what would the select statement look
like, i.e, how do I reference the produce list?

Currently I have something like this:
<%= f.select :produce_id, Order.produce_list %>

something like…
<%= f.select :procude_id,
options_from_collection_for_select(@grocery.produces, “id”, “name”) %>

hth…

ilan

Of possible interest–this very similar thread:

http://groups.google.com/group/rubyonrails-talk/browse_frm/thread/16eff66dda41b846

If you want to emulate that (and I’m a pretty big noob, so you may
not) you’d put that function in the Customer model I think…

HTH,

-Roy

On Feb 22, 2:52 pm, Becca G. [email protected]

Controller logic should be confined to user interface logic.
The Models should be where the logic related to “business” rules
lives. By model here I mean primarily ActiveRecord models in Rails,
although these can be supplemented or even replaced in some
applications.

Another way to say this: Anything a user can do to the data, thru the
View, a
unit test can do to the data, thru the Model.

Controllers should add no business rules.

(I’ll get back to you when all the Rails apps I maintain follow that
rule!:wink:

On 2/22/08, Ilan B. [email protected] wrote:

listed above then it’s find to ask the model for a list from the
controller.

Controllers are solely responsible for mapping views to models. Their
functionality should be focussed around this task. If a controller
doesn’t need to have access to a model’s state (which is the preferred
way) then it shouldn’t.

Lastly, a model should never have ANY knowledge of it’s business context
within the application. It should be completely application agnostic.

Actually this advice goes against the prevailing wisdom that
controllers should be skinny and models should be fat.

http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model
http://therailsway.com/2007/6/1/railsconf-recap-skinny-controllers
http://www.robbyonrails.com/articles/2007/06/19/put-your-controllers-on-a-diet-already

I’m not sure what business logic really means, there’s no real
definition of it. But in general:

Views should have very little code, and what’s there should be dealing
with presentation NOT the domain model.
Controller logic should be confined to user interface logic.
The Models should be where the logic related to “business” rules
lives. By model here I mean primarily ActiveRecord models in Rails,
although these can be supplemented or even replaced in some
applications.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Thanks so much for the great help! There’s a bit of conflicting advice,
but you guys are great! Thanks for the links too.

Phlip wrote:

Controller logic should be confined to user interface logic.
The Models should be where the logic related to “business” rules
lives. By model here I mean primarily ActiveRecord models in Rails,
although these can be supplemented or even replaced in some
applications.

Another way to say this: Anything a user can do to the data, thru the
View, a
unit test can do to the data, thru the Model.

Controllers should add no business rules.

(I’ll get back to you when all the Rails apps I maintain follow that
rule!:wink:

Rick and Phlip phrased it much better than I… sorry if this lead to
some confusion…

ilan