From: Josh Cheek Date: 2009-08-20T10:52:54+09:00 Subject: Re: exercise in DRY --000e0cd482766b88be047189020c Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi, Peter, If you have that many <% ... %> all in a row, and are placing that much logic into your view, then you are probably ripe for a helper :) In the file app/helpers/tweet_helper.rb you can declare a method like def agree_and_disagree(tweet) if tweet.votedOn == 1 #agree a"#{tweet.agree_count - 1} + 1" disagree = tweet.disagree_count.to_s elsif tweet.votedOn == 0 #disagree disagree = "#{tweet.disagree_count - 1} + 1" agree = tweet.agree_count.to_s elsif tweet.votedOn == 2 #neutral agree = tweet.agree_count.to_s disagree = tweet.disagree_count.to_s end [agree , disagree] end This can be refactored a bit, into def agree_and_disagree(tweet) if tweet.votedOn == 1 #agree ["#{tweet.agree_count - 1} + 1" , tweet.disagree_count.to_s] elsif tweet.votedOn == 0 #disagree ["#{tweet.disagree_count - 1} + 1" , tweet.agree_count.to_s] elsif tweet.votedOn == 2 #neutral [tweet.agree_count.to_s , tweet.disagree_count.to_s] end end Which cleans up your view code, you can then assign the values with something like <% if tweet.votedOn != nil -%> <% agree , disagree = agree_and_disagree(tweet) %> <%= agree %> – <%= disagree %> <% else -%> ... Also, to make your code more readable and intuitive, you can take if tweet.votedOn == 1 #agree elsif tweet.votedOn == 0 #disagree elsif tweet.votedOn == 2 #neutral And create methods for these in your model (or the tweet's class, however you have it defined). Something like class Tweet < ActiveRecord::Base ... def agree?() votedOn == 1 end def disagree?() votedOn == 0 end def neutral?() votedOn == 2 end end Then your helper code can be just if tweet.agree? elsif tweet.disagree? elsif tweet.neutral? You can, of course, name these whatever you think makes them the most readable and is the most memorable. This means that you don't have to remember that they agree if votedOn is equal to some internally defined value, it helps keep those values inside the class, and just provides intuitive, self-descriptive methods as an interface. After you get that class made, you should ideally never have to know that 1 means agree, and so on. That can all be handled internally, making your class easier to work with. (If you are working with this class a lot, you'll thank yourself later for establishing a nice set of methods to encapsulate internal logic). Also, FWIW, if you don't like passing arguments in the URL, you can define a route like /tweets/agree/:id/agree /tweets/agree/:id/disagree By declaring them as members in your routes and having methods in your controller for them to invoke. If you are interested in that, here is a wonderful guide on routing http://guides.rubyonrails.org/routing.html#adding-more-restful-actions On Wed, Aug 19, 2009 at 6:17 PM, Peter Ehrlich wrote: > So for anyone curious, here's how I wound up doing it: > (no haml just because I'm too busy learning rails and ruby already :-) > > It probably could be made more dry, but this is pretty good and has the > benefit of being written. I haven't included the controller, because > its a bit more complex, dealing with different databases of anonymous > and non-anonymous users.. > > ==== _agree_field.erb ==== > <% #logger.debug "view agree: " + tweet.votedOn.to_s -%> > <% if tweet.votedOn != nil -%> > <% if tweet.votedOn == 1 #agree %> > <% agree = "#{tweet.agree_count - 1} + 1" %> > <% disagree = tweet.disagree_count.to_s %> > <% elsif tweet.votedOn == 0 #disagree%> > <% disagree = "#{tweet.disagree_count - 1} + 1" %> > <% agree = tweet.agree_count.to_s -%> > <% elsif tweet.votedOn == 2 #neutral -%> > <% agree = tweet.agree_count.to_s -%> > <% disagree = tweet.disagree_count.to_s %> > <% end %> > <%= agree %> > – > <%= disagree %> > <% else -%> > > > <%= link_to_remote('Agree', :update => "#{tweet.dom_id}_c", :url > => "/tweets/agree/#{tweet.id}?agree=true") %> > > <%= link_to_remote('–', :update => "#{tweet.dom_id}_c", :url > => "/tweets/agree/#{tweet.id}")%> > > <%= link_to_remote('Disagree', :update => "#{tweet.dom_id}_c", > :url => "/tweets/agree/#{tweet.id}?agree=false")%> > > > <% end -%> > > > Cheers, > --Peter > -- > Posted via http://www.ruby-forum.com/. > > --000e0cd482766b88be047189020c--