# How would you take the duplication out of this?

**URL:** <https://www.ruby-forum.com/t/how-would-you-take-the-duplication-out-of-this/94025>\
**Category:** Rails\
**Created:** [April 18, 2006, 8:58am UTC](https://www.ruby-forum.com/t/how-would-you-take-the-duplication-out-of-this/94025 "2006-04-18T08:58:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![travis\_laduke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e95f7d/32.png) [@travis\_laduke](https://www.ruby-forum.com/u/travis_laduke)\
**Post date:** [April 18, 2006, 8:58am UTC](https://www.ruby-forum.com/t/how-would-you-take-the-duplication-out-of-this/94025/1 "2006-04-18T08:58:59Z")

</div>

i have these two really similar methods in my addressbook controller.

def edit\_company  
@company = Company.find(params[:id])  
if request.post? and @company.update\_attributes(params[:company])  
flash[:notice] = ‘Company was successfully edited.’  
redirect\_to :action =\> ‘show’, :id =\> @company  
end  
end  
def edit\_person  
@person = Person.find(params[:id])  
if request.post? and @person.update\_attributes(params[:person])  
flash[:notice] = ‘Person was successfully edited.’  
redirect\_to :action =\> ‘show’, :id =\> @person  
end  
end

it really bugs me that they are pretty much the same methods

travis

---

<div class="post-metadata">

**Author:** ![travis\_laduke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e95f7d/32.png) [@travis\_laduke](https://www.ruby-forum.com/u/travis_laduke)\
**Post date:** [April 18, 2006, 9:24am UTC](https://www.ruby-forum.com/t/how-would-you-take-the-duplication-out-of-this/94025/2 "2006-04-18T09:24:10Z")

</div>

travis laduke wrote:

> i have these two really similar methods in my addressbook controller.
> 
> def edit\_company  
> @company = Company.find(params[:id])  
> if request.post? and @company.update\_attributes(params[:company])  
> flash[:notice] = ‘Company was successfully edited.’  
> redirect\_to :action =\> ‘show’, :id =\> @company  
> end  
> end  
> def edit\_person  
> @person = Person.find(params[:id])  
> if request.post? and @person.update\_attributes(params[:person])  
> flash[:notice] = ‘Person was successfully edited.’  
> redirect\_to :action =\> ‘show’, :id =\> @person  
> end  
> end
> 
> it really bugs me that they are pretty much the same methods

You could be lazy and cheat:

for model\_class in %w(company person)  
module\_eval \<\<-“end;”  
def edit\_#{model\_class}  
@#{model\_class} = #{model\_class.titleize}.find(params[:id])  
# you get the idea…  
end  
end;  
end

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

---

<div class="post-metadata">

**Author:** ![travis\_laduke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e95f7d/32.png) [@travis\_laduke](https://www.ruby-forum.com/u/travis_laduke)\
**Post date:** [April 18, 2006, 9:32am UTC](https://www.ruby-forum.com/t/how-would-you-take-the-duplication-out-of-this/94025/3 "2006-04-18T09:32:43Z")

</div>

travis laduke wrote:

> i have these two really similar methods in my addressbook controller.
> 
> def edit\_company  
> @company = Company.find(params[:id])  
> if request.post? and @company.update\_attributes(params[:company])  
> flash[:notice] = ‘Company was successfully edited.’  
> redirect\_to :action =\> ‘show’, :id =\> @company  
> end  
> end  
> def edit\_person  
> @person = Person.find(params[:id])  
> if request.post? and @person.update\_attributes(params[:person])  
> flash[:notice] = ‘Person was successfully edited.’  
> redirect\_to :action =\> ‘show’, :id =\> @person  
> end  
> end
> 
> it really bugs me that they are pretty much the same methods
> 
> travis

Ok, I’m sure there must be a better way, but here’s one option:

def edit\_record model\_name  
instance\_var = “@#{model\_name}”  
model = model\_name.camelize.constantize  
instance\_variable\_set instance\_var, model.find(params[:id])  
if request.post? and  
instance\_var.update\_attributes(params[model\_name.to\_sym])  
flash[:notice] = “#{model\_name.camelize} was successfully edited.”  
redirect\_to :action =\> ‘show’, :id =\> instance\_var  
end  
end

Then you could call:

edit\_record ‘company’

edit\_record ‘person’

Jeff C.man

---

<div class="post-metadata">

**Author:** ![travis\_laduke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e95f7d/32.png) [@travis\_laduke](https://www.ruby-forum.com/u/travis_laduke)\
**Post date:** [April 18, 2006, 6:59pm UTC](https://www.ruby-forum.com/t/how-would-you-take-the-duplication-out-of-this/94025/4 "2006-04-18T18:59:15Z")

</div>

2006/4/18, travis laduke [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> it really bugs me that they are pretty much the same methods

The first thing you need to do, is work out what is different between  
the two methods.

As you wrote them, I see these differences:

@company vs @person  
Person vs Company  
‘Person’ vs ‘Company’  
params[:company] vs params[:person]

Next, you need to work out what the “best” code would look like for  
inside the two actions. Something like this might be good:

def edit\_company  
@company = find\_or\_redirect(Company)  
end

def edit\_person  
@person = find\_or\_redirect(Person)  
end

So, what does find\_by\_id\_or\_redirect look like? If we can work out  
each of the differences simply by knowing which Class we’re talking  
about, then we can use the two methods above.

The first difference is which instance variable to assign to. As you  
can see in the two methods above, I’m setting the instance variables  
by whatever is returned from find\_or\_redirect, so that’s easy.

Next, Person vs Company. That’s easy too, as I’m supplying it as an  
argument.

Next, ‘Person’ vs ‘Company’, used in your flash message. That’s just  
the name of the class as a string, so we can get that using  
Person.to\_s.

Lastly, params[:company] vs params[:person]. Here, it’s the name of  
the class, converted to lowercase (downcase), and then converted into  
a symbol. So we can do: Person.to\_s.downcase.to\_sym to get the symbol.

Bringing that all together, we get:

def edit\_company  
@company = find\_or\_redirect(Company)  
end

def edit\_person  
@person = find\_or\_redirect(Person)  
end

protected

def find\_or\_redirect(klass)  
item = klass.find(params[:id])  
klass\_symbol = klass.to\_s.downcase.to\_sym  
if request.post? and item.update\_attributes(params[klass\_symbol])  
flash[:notice] = “#{klass.to\_s} was successfully edited.”  
redirect\_to :action =\> ‘show’, :id =\> item  
end  
return item  
end

And that should work fine 🙂

hth,  
Douglas

---

<div class="post-metadata">

**Author:** ![travis\_laduke](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e95f7d/32.png) [@travis\_laduke](https://www.ruby-forum.com/u/travis_laduke)\
**Post date:** [April 18, 2006, 4:31pm UTC](https://www.ruby-forum.com/t/how-would-you-take-the-duplication-out-of-this/94025/5 "2006-04-18T16:31:24Z")

</div>

In this case, taking the duplication out of it makes it more complex. I  
wouldnt bother if i were you. Too much drying makes you wrinkly 😉
