Ruby: more readable way to write nested if conditions? [closed] - ruby-on-rails

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is there a more readable way in Ruby (or using Rails model helpers) to write the following:
def get_question
if self.is_question?
self.trackable
elsif self.is_answer?
self.trackable.question
elsif self.is_comment?
if self.trackable.is_question?
self.trackable.commentable
elsif self.trackable.is_answer?
self.trackable.commentable.question
end
end
end
There must be a more "Ruby way" of writing this so it's easier to read for other developers.

I tend to write that sort of thing like this:
def get_question
return self.trackable if self.is_question?
return self.trackable.question if self.is_answer?
return nil if !self.is_comment?
return self.trackable.commentable if self.trackable.is_question?
return self.trackable.commentable.question if self.trackable.is_answer?
return nil
end
that's pretty mu-idiomatic but I don't know if it qualifies as Ruby-idiomatic. Yes, there's an unnecessary return at the end but I like the symmetry and how it makes everything visually line up.
In real life, I'd probably want replace all that logic with a question method on the self.trackable. Then each thing could implement question (or to_question, get_question, or whatever name made the most sense in the broader context):
# Inside questions...
def question
self
end
# Inside answers...
# Nothing special needed, we've already got one.
and so on for the other possible possible self.trackable things. That would leave your get_question looking like this:
def get_question
self.trackable.respond_to?(:question) ? self.trackable.question : nil
end
or you could do away with get_question completely if you knew that self.trackable would also respond to question.

Related

Making mailer functions more DRY [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Inside a mailer file, I have 11 methods all of which start with the line
#reservation = reservation
Is there a way to make this DRY? I tried the following:
def set_reservation
#reservation = reservation
end
and then
before_action :set_reservation
Unfortunately, this always gave me something along these lines:
AgentReservationMailer#send_reserve_complete_mail: processed outbound mail in 1.7ms
NameError: undefined local variable or method `reservation' for #<AgentReservationMailer:0x007ffc9ae5bb38>
I'm still a very junior level developer, but I would like to try and make things look as professional as I can - is what I am trying to do even possible though?
The reason you're seeing the error is that the mailer does not know of a variable reservation inside the set_reservation method. I'm assuming that the 11 methods you mention, which use the
#reservation = reservation
take reservation as an argument. As it stands, there really is no need to try and reduce duplication.
As a side note, DRY is not a principle you should follow blindly. If you had a couple of lines that were the same in each method, then that would indeed justify an "extract method" refactoring. But replacing that #reservation = reservation assignment with e.g. a method call set_reservation(reservation), you'd still end up repeating one line across all methods.

using an external .rb in a controller [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I currently have a separate .rb file that contains smth like this:
if lang == 'fr'
#a = 'AAAAAAA'
#b = 'BBBBBBB'
#c = 'CCCCCCC'
else
#a = 'sadadddsad'
#b = 'dsafdsfdasfdsa'
#c = 'dsadasfdsfsfd'
end
, only with a lot more strings.
Being a large library of strings, and wanting to keep this in one place as these will be used in multiple controllers and functions within, what is a good method to call these files from inside a function in controllers?
Looks like you want to use Internationalization in your app. You could follow this link http://guides.rubyonrails.org/i18n.html to know more and its implementation.

Convention: if (!foo) vs unless (foo). And while (!foo) vs until (foo) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am learning Ruby along with RoR and noticed that instead of using
if !foo
ruby provides
unless foo
In addition, instead of:
while !foo
we have
until foo
Coming from C++/Java, it seems to just confuse me when I read unless/until. Does it seem like people who program a lot in ruby conventionally use unless/until instead of just negating if/while?
Is this something I should just get used to or do you see a lot of variance on the subject?
Thanks!
Yes, using unless condition instead of if !condition is common and idiomatic.
unless foo
# ...
end
It's especially common to use as a post condition:
# Bad
raise "Not Found" if !file_exists?(file_name)
# Good
raise "Not Found" unless file_exists?(file_name)
When in doubt, follow ruby-style-guide
From the syntax section of the ruby style guide:
Favor unless over if for negative conditions (or control flow ||).
# bad
do_something if !some_condition
# bad
do_something if not some_condition
# good
do_something unless some_condition
# another good option
some_condition || do_something
And
Favor until over while for negative conditions.
# bad
do_something while !some_condition
# good
do_something until some_condition

Ruby attribute meta programming [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
My user has the attribute:
:step1_local
:step2_local
:step3_local
...
...
:local1
:local2
:local3
I would like to change an attribute value based on another set of attributes on the same model. I would like to do some processing mapping on user, say:
def magic (user)
user.local(1..3) = process(user.step(1..3)_local)
end
The code above of course does not work (example). I am not sure how to do it dynamically without going through each attributes individually. I want to map processing one to another. Any ideas?
You can use Object#public_send and method, like this:
def magic(user)
(1..3).each do |n|
user.public_send("local#{n}=", process(user.read_attribute("step#{n}_local")))
end
end

What's the best way to resize thousands images using paperclip and rails? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have a model with 6 paperclip photos (photo1, photo2, photo3, photo4, photo5 and photo6).
Because recently changes on design of site i need to resize all style on the six pictures. The styles are small, medium and large.
My idea is use a before filter method to do a Model.photo1.reprocess! and add a column to model table (for example "reprocess" as boolean) to check if it's was reprocessed or not.
This idea i think it's more eficcient than use a rake script to migrate all photos in one single migration with the next deploy.
Product Controller
before_filter :check_image_reprocess, :only => [:show]
def check_image_reprocess
#product = Product.find(params[:id])
if #product.reprocess == false
#product.photo.reprocess! unless #product.photo.nil?
#product.photo2.reprocess! unless #product.photo2.nil?
#product.photo3.reprocess! unless #product.photo3.nil?
#product.photo4.reprocess! unless #product.photo4.nil?
#product.photo5.reprocess! unless #product.photo5.nil?
#product.photo6.reprocess! unless #product.photo6.nil?
#product.update_attributes(:reprocess => true)
end
end
Actually it's works, but if exists any comments about this or better suggestions, there will be very welcome :) ?
Thanks in advance
This way it's working perfectly after 1 week of testing !!
Enjoy

Resources