When to use percent i method to create arrays with symbols? [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 4 years ago.
Improve this question
In Ruby there is a nifty method of creating an array of symbols.
Percent i method.
%i[a b c]
I am working in a team based environment, and although I can see this being useful with a large list of array, I have this is being implemented for everything
a = %i[] # Empty array
cancan abilities
can :manage, :all
cannot %i[create show update], AModel
cannot %i[create], BModel
cannot %i[show], CModel
Is it good to initialize all arrays using this methods or just
cannot [:create, :show, :update], AModel
I know there is no 'right' way but I would like the pros and cons to help me decide

In terms of the language itself, there are no important differences between the two, so it really comes down to a matter of preference. Personally, I think that the array of symbol literals ([:create, :show, :update]) looks more Ruby-like and that is what I'd use, but you should discuss it with your team. The most important part is being consistent, and you don't want to make the decision alone.
In the general case of when to use %i instead of writing out a literal array of symbols, I'd consider using the former if it was a list of symbols that had certain meaning, like a class constant or something, and there were more than just a couple. I've been using Ruby for a while now and until this question didn't really register the existence of %i, so it's relatively uncommonly used. It's maybe not in the average Rubyist's vocabulary, so that might be another reason to stay away from it.

Related

Best practices and code for generating booking reference number? [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 2 years ago.
Improve this question
I would like to generate booking reference numbers so they can easily be communicated by voice, written down, texted etc.
I currently use uuid, which works well, but results in poor UX, as strings like 510632cc-3aa4-41c2-8bd0-cbd2bd671ef4 are difficult to communicate.
Here is an Airbnb booking reference, which is nice and short and easy to communicate verbally:
Best practices
I gave it some thought and decided on using all capital letters except O (and no lower case letters), and the numbers 1-9.
This results in 25 + 9 = 34 possible characters. There could therefore be
34^6 = 1544804416 (1.5 billion) 6-character codes
Or if that isn't enough, 34^7 = 52523350144 (52 billion) 7-character codes
In my use case 6-characters is ample.
To summarise, the booking_reference should be a random string of letters A-Z except O, and numbers 1 -9 (not 0), no lower case letters. And the column must be unique - no duplicate strings.
Question
Have I encapsulated best practices in my ideas above, and, presuming I create a booking_reference column to store the string, how can I generate these in the bookings#create controller action?
Note: I'm not sure if it's relevant to the ruby tag; please feel free to remove that tag if it isn't relevant.
You should not do this in your controller.
This example below will generate a 8-character booking reference before creating your record, no zeros and Os. Note that it doesn't look for collisions, you should elaborate on that if you expect a lot of records, there are many different ways to do it including model validations and so on. You might also want to add an index on booking_reference to your table.
class YourModel < ApplicationRecord
# ...
before_create :generate_booking_reference
def generate_booking_reference
self.booking_reference = 8.times.map { [*'1'..'9', *'a'..'n', *'p'..'w'].sample }.join
# TODO check for collisions
end
# ...
end

rails: keep it DRY, to what level? [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 4 years ago.
Improve this question
We always read people saying "keeps things dry" with rails. But to what level?
For example, we have 3 models Project, Offer, Revision. This 3 models can have many Attachment.
On the "models" side it is quite straight forward we end up with
/app/models/project.rb
/app/models/offer.rb
/app/models/revision.rb
But for the controllers side I have problems keeping it DRY. I end up with at least:
GET /projects/:id/attachments -> Projects/Attachments#index
POST /projects/:id/attachments -> Projects/Attachments#create
GET /offers/:id/attachments -> Offers/Attachments#index
POST /offers/:id/attachments -> Offers/Attachments#create
GET /revisions/:id/attachments -> Revisions/Attachments#index
POST /revisions/:id/attachments -> Revisions/Attachments#create
So basically, I've almost the same code in this 3 locations:
controllers/projects/attachments_controller.rb
controllers/offers/attachments_controller.rb
controllers/revisions/attachments_controller.rb
My question, should I DRY it up and how?
DRY or "don't repeat yourself" is a general rule of thumb.
in case you find a pattern in your code that repeats itself in several places it might be worth looking into it.
if it's possible to extract a common functionality into, say a module, then you should probably do that.
if you think it's not worth your time, to complex or whatever reason there is not to do it, that is totally fine.
KISS (keeping things simple and stupid) > DRY
make sure your code is simple to follow and refactor and DRY out afterwards.

Ruby dynamically build and assign varibles [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 am building a rails app that i need to update totals of managers each time someone is added. The method that updates the totals to me is looking really bad there is a lot of repetition going on that could be solved with a bit of metaprogramming. so i have a private method being called on before_save called update_totals
So we categorize them like this there is four races, african, coloured, indian and white there are three kinds of managements senior, middle and junior and then obviously two kinds of genders male and female. I need to be able to assign each possible variation of the three so i end up with something like this.
self.number_of_african_female_senior_managers = managers.native.african.female.senior.count
self.number_of_african_male_senior_managers = managers.native.african.male.senior.count
self.number_of_african_female_middle_managers = managers.native.african.female.middle.count
self.number_of_african_male_middle_managers = managers.native.african.male.middle.count
self.number_of_african_female_junior_managers = managers.native.african.female.junior.count
self.number_of_african_male_junior_managers = managers.native.african.male.junior.count
I would need to do this for each race. So i thought of building them dynamically and then having them assigned.
So something like this:
["african", "indian", "coloured", "white"].each do |race|
["senior","middle","junior"].each do |management_type|
["male","Female"].each do |gender|
"number_of_#{race}_#{gender}_#{management_type}_managers" = managers.native.race.gender.management_type.count
end
end
end
But this will return strings and not variables that be assigned. I saw there is a define_method method that can dynamically build methods but that looks like you have to call it outside of the constructor in this example, and i saw that you can use Object#send like this example, but i cant see that working in this situation either.
Is this a good ruby practice? Its adding a bit of complexity but removing a lot of DRY code.
Is this a good ruby practice?
DRY is a good ruby practice, so the answer to your question is: YES
Regarding your code you will probably use send in such a situation.
something like self.send("number_of_#{race}_#{gender}_#{management_type}_managers=", managers.send(native).send(race).send(gender).send(management_type).count)
This still looks pretty ugly to me. I am kind of asking myself why that datastructure is so insane. Why are you not using a simple hash structure here?

Ruby/ROR Symbols Clarification [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 8 years ago.
Improve this question
I'm new to Ruby/ROR and I'm kind of confused with something. A simple explanation would help.
Say I was linking to another page in Ruby on Rails. Would the keyword link_to be considered a method? Also, if so, where would I be able to learn more about these?
Symbols. What is the difference between a symbol with a colon on the :left or a symbol with a colon on the right:? Where would I be able to learn more about these?
You could use Google, e.g. https://www.google.de/search?q=rails+link_to. The link_to method is, well, a method which is defined by Rails and is not a Ruby keyword.
Symbols are different from Strings. In Ruby code, they are always written with a colon on the left. An "exception" of this rule is when it is used in a Hash using the new json-like Hash syntax from Ruby 1.9, where {foo: "bar"} is equivalent to {:foo => "bar"} Which variant you use is up to you, they are 100% equivalent.
Generally, it is probably a good idea to first read an introductional book about both Ruby and Rails or take an online-course, e.g. http://ruby.railstutorial.org/ for learning Rails or http://rubykoans.com/ for learning Ruby.

Design advice for file parser [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 4 years ago.
Improve this question
I am trying to design an edifact parser, I was planning on having one class to read the file, one class to map the data and then one other class to deal with data storage. The part where I am having a major problem is in how instances of those classes should communicate with each other. Any advice would be appreciated.
I don't see a need for the classes to communicate (pass messages) but would suggest some Strategy pattern be used.
You'll have a class to read the file and make sense of it's Syntax. For example, something which can handle whitespace and return formatted information like 'token', 'word' etc.
The class which reads and parses syntax is passed into the Semantic parser. The Semantic parser makes sense of the meaning. For example you might expect "Id, command, token, string" in that order. The Semantic parser might use a Command pattern.
The Semantic class outputs structured data, so is passed into your structure builder (builder pattern).
So your code might look like;
MyDataStructure = DataBuilder(SemanticParser(SyntaxParse(FileReader(filename))));
HTH

Resources