I could really use some help with the best way to accomplish the following:
I have the below in my controller (and I know this should not be here and needs to move to the model)
This is an email messaging system so according to what position you hold you are able to email out to set groups of people. So if you are Battalion Commander etc you can choose to message out to one of the 5 groups defined below. If you are a Company Commander your groups change. In the view there is a drop down menu and you choose the group your message goes out to. The select menu is populated depending on the position of the signed in user.
The problem seems that the "elsif" portion does not populate the message correctly. It shows the right drop down list and acts as if the email is sent but the emails are not being populated. However the first value (Battalion Commander) works fine.
Do I have something written incorrectly in the if else statement? It seems like it should be pretty simple. The user position always reflects correctly so that is not it.
if (#position == "Battalion Commander" or "Command Sergeant Major" or "FRSA" or "Battalion FRG Leader")
#bnok = (#user.battalion.primaries).collect(&:email).select{|s| !s.blank?}.join(", ")
#bspouses = (#user.battalion.primaries(:conditions => ["relationship = 'spouse'"])).collect(&:email).select{|s| !s.blank?}.join(", ")
#bsoldiers= (#user.battalion.soldiers).collect(&:email).select{|s| !s.blank?}.join(", ")
#bsoldierspouse=((#user.battalion.soldiers)+(#user.battalion.primaries(:conditions => ["relationship = 'spouse'"]))).collect(&:email).select{|s| !s.blank?}.join(", ")
#ballcontacts=((#user.battalion.soldiers)+(#user.battalion.primaries)+(#user.battalion.additionals)).collect(&:email).select{|s| !s.blank?}.join(", ")
elsif
#position == ("Company Commander" or "First Sergeant" or "FRG Leader")
#nok = (#user.company.primaries).collect(&:email).select{|s| !s.blank?}.join(", ")
#spouses = (#user.company.primaries(:conditions => ["relationship = 'spouse'"])).collect(&:email).select{|s| !s.blank?}.join(", ")
#soldiers= (#user.company.soldiers).collect(&:email).select{|s| !s.blank?}.join(", ")
#soldierspouse=((#user.company.soldiers)+(#user.company.primaries(:conditions => ["relationship = 'spouse'"]))).collect(&:email).select{|s| !s.blank?}.join(", ")
#allcontacts=((#user.company.soldiers)+(#user.company.primaries)+(#user.company.additionals)).collect(&:email).select{|s| !s.blank?}.join(", ")
end
So this does not work, it work for either one set of positions or the other but not both. This correlates to a select menu in the view and depending on what position you hold the query on certain groups of people change.
So in the view I have this:
<% if #position == "Battalion Commander" %>
<%= f.select(:bcc_email, [["Please Select", ""], ["Battalion NOK", #bnok], ["Battalion Spouses", #bspouses], ["Battalion Soldiers Only", #bsoldiers], ["Battalion Soldiers & Spouses", #bsoldierspouse], ["All Battalion Contacts", #ballcontacts]]) %></h1><br />
I am still learning rails and I am not sure if a case statement would be better but then I am confused on where that goes and how that case statement fits into the view.
Any guidance would be great, I am trying to chip away at this and figure it out, but I would really appreciate some help.
Firstly it may help if you can format that a bit clearer - for us and yourself, often simple formatting will help identify issues.
Secondly, what is your goal here? I gather it's some sort of war simulator or something? And assume you realise that in an if statement, only one of them will be executed:
if (xxx)
aaaaaaaaaaaaaaaaaa
elseif (yyyy)
bbbbbbbbbbbbbb
end
in the case that xxx is true, the aaaaaaaa will be executed, and then it'll jump to end. The bbbbbbbbb part will not be executed - even if true, because the first statement was. If however xxx is not true, yyyy will be evaluated, and if true, bbbbbbbbbbbbb will happen.
I hope that helps a bit?
disclaimer: I don't know ruby. I have been told it is similar to python and LISP in some regards, so this answer makes that assumption.
What I would do is maintain these condition variables in a dictionary (or map, or hash table, whatever your language calls it). The "rank" of the person would be a key, and the value would correspond to the function you want to execute for that rank. for instance,
#the following example is python-esque. you'll have to port it to ruby.
def some_funct1(): #pass parameters if you need to. i don't, here.
sql_stuff_here
def some_funct2():
sql_stuff_here
map['important dude'] = some_funct1;
map['another important dude'] = some_funct1;
map['unimportant dude'] = some_funct2;
map['another_unimportant dude'] = some_funct2;
#after some time, you have a person whose rank is rank.
map[rank]() #this will execute the function
You wrote
if (... a big test ...)
..do some work..
elsif
..do something else..
end
but that is wrong! You should just write else instead of elsif unless you need to check another condition.
[I assume elsif followed by nothing=nil is always false]
Related
This is code I have using in my project.
Please suggest some optimizations (I have refactored this code a lot but I can't think of any progress further to optimize it )
def convert_uuid_to_emails(user_payload)
return unless (user_payload[:target] == 'ticket' or user_payload[:target] == 'change')
action_data = user_payload[:actions]
action_data.each do |data|
is_add_project = data[:name] == 'add_fr_project'
is_task = data[:name] == 'add_fr_task'
next unless (is_add_project or is_task)
has_reporter_uuid = is_task && Va::Action::USER_TYPES.exclude?(data[:reporter_uuid])
user_uuids = data[:user_uuids] || []
user_uuids << data[:owner_uuid] if Va::Action::USER_TYPES.exclude?(data[:owner_uuid])
user_uuids << data[:reporter_uuid] if has_reporter_uuid
users_data = current_account.authorizations.includes(:user).where(uid: user_uuids).each_with_object({}) { |a, o| o[a.uid] = {uuid: a.uid, user_id: a.user.id, user_name: a.user.name} }
if Va::Action::USER_TYPES.include? data[:owner_uuid]
data['owner_details'] = {}
else
data['owner_details'] = users_data[data[:owner_uuid]]
users_data.delete(data[:owner_uuid])
end
data['reporter_details'] = has_reporter_uuid ? users_data[data[:reporter_uuid]] : {}
data['user_details'] = users_data.values
end
end
Note that Rubocop is complaining that your code is too hard to understand, not that it won't work correctly. The method is called convert_uuid_to_emails, but it doesn't just do that:
validates payload is one of two types
filters the items in the payload by two other types
determines the presence of various user roles in the input
shove all the found user UUIDs into an array
convert the UUIDs into users by looking them up
find them again in the array to enrich the various types of user details in the payload
This comes down to a big violation of the SRP (single responsibility principle), not to mention that it is a method that might surprise the caller with its unexpected list of side effects.
Obviously, all of these steps still need to be done, just not all in the same method.
Consider breaking these steps out into separate methods that you can compose into an enrich_payload_data method that works at a higher level of abstraction, keeping the details of how each part works local to each method. I would probably create a method that takes a UUID and converts it to a user, which can be called each time you need to look up a UUID to get the user details, as this doesn't appear to be role-specific.
The booleans is_task, is_add_project, and has_reporter_uuid are just intermediate variables that clutter up the code, and you probably won't need them if you break it down into smaller methods.
I am making a script inside TextButton script that will check if the TextBox contains any of the word or string inside the table.
text = script.Parent.Parent:WaitForChild('TextBox')
label = script.Parent.Parent:WaitForChild('TextLabel')
a = {'test1','test2','test3'}
script.Parent.MouseButton1Click:connect(function()
if string.match(text.Text, a) then
label.Text = "The word "..text.Text.." was found in the table."
else
label.Text = "The word "..text.Text.." was not found in the table."
end
end)
But it gives an error string expected, got table. from line 7 which is refering to the line if string.match....
Is there any way to get all text in the table?
What's the right way to do it?
Oh boy, there's a lot to say about this.
The error message
Yes.
No, seriously, the answer is yes. The error message is exactly right. a is a table value; you can clearly see that on the third line of code. string.match needs a string as its second argument, so it obviously crashes.
Simple solution
use a for loop and check for each string in a separately.
found = false
for index, entry in ipairs(a) do
if entry == text.Text then
found = true
end
end
if found then
... -- the rest of your code
The better* solution
In Lua, if we want to know if a single element is in a set, we usually take advantage of the fact that tables are implemented as hashmaps, meaning they are very fast when looking up keys.
For that to work, one first needs to change the way the table looks:
a = {["test1"] = true, ["test2"] = true, ["test3"] = true}
Then we can just index a with a string to find out if it is contained int eh set.
if a[text.Text] then ...
* In practice this is just as good as the first solution as long as you only have a few elements in your table. It only becomes relevant when you have a few hundred entries or your code needs to run absolutely as fast as possible.
I got a few string like so:
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_light_87689uiyhk
AND
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_light_87689uiyhk
AND
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_dark_87689uiyhk
AND
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_dark_87689uiyhk
I need to check whether the strings above has one of the widesky_light, sky_light, widesky_dark and sky_dark with exactitude so I wrote this:
if my_string.match("widesky_light")
...
end
For each variant, but the problem I'm having is because sky_light and widesky_light are similar, my code is not working properly. I believe the solution to the above would be a regex, but I've spend the afternoon yesterday trying to get it to work without much success.
Any suggestions?
EDIT
A caveat: in this string (as example): TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_light_87689uiyhk, the part after widesky_light, which is _87689uiyhk is optional, meaning that sometimes I have it, sometimes I don't, so a solution would not be able to count on _string_.
Looks like you just need to reorder your if statements
if my_string.match(/widesky_light/)
return 'something'
end
if my_string.match(/sky_light/)
return 'something'
end
Regex
1st regex : extract word for further checking
Here's a regex which only matches the interesting part :
(?<=_)[a-z_]+(?=(?:_|\b))
It means lowercase word with possible underscore inside, between 2 underscores or after 1 underscore and before a word boundary.
If you need some logic depending on the case (widesky, sky, light or dark), you could use this solution.
Here in action.
2nd regex : direct check if one of 4 words is present
If you just want to know if any of the 4 cases is present :
(?<=_)(?:wide)?sky_(?:dark|light)(?=(?:_|\b))
Here in action, with either _something_after or nothing.
Case statement
list = %w(
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_light_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_light_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_widesky_dark_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_sky_dark_87689uiyhk
TFjyg9780878_867978-DGB097908-78679iuhi698_trash_dark_87689uiyhk
)
list.each do |string|
case string
when /widesky_light/ then puts "widesky light found!"
when /sky_light/ then puts "sky light found!"
when /widesky_dark/ then puts "widesky dark found!"
when /sky_dark/ then puts "sky dark found!"
else puts "Nothing found!"
end
end
In this order, the case statement should be fine. widesky_dark won't match twice, for example.
Maybe something like this:
case my_string
when /_(sky_light)/
# just sky_light
when /sky_light/
# widesky_light
when /_(sky_dark)/
# just sky_dark
when /sky_dark/
# widesky_dark
else
puts "I don't like"
end
I want to make a translation my_translation with an optional parameter. For example:
> I18n.t('my_translation')
=> "This is my translation"
> I18n.t('my_translation', parameter: 1)
=> "This is my translation with an optional parameter which value is 1"
Is this possible?
Yes, definitely. You just write the translations like this:
my_translation: This is my translation with an optional parameter which value is %{parameter}
Is the parameter really optional? In above translation, you have to provide all parameters.
UPDATE: Sorry, I answered too soon. I don't think it's easy to do. Maybe the easiest way is like this:
> I18n.t('my_translation1')
=> "This is my translation"
> I18n.t('my_translation2', parameter: 1)
=> "This is my translation with an optional parameter which value is 1"
I would say it is possible, though not recommended. You have two completely separate strings, based on your comments in #Yanhao's answer, and I would say they should be two separate entries in your yaml file:
report_name: My report
report_name_with_date: My report on %{date}
Since the existence of the date determines which string to display, you could perhaps test for its existence in in the params hash in a controller method, assign the title to a variable, and then use it in a view. Perhaps something like:
report_date = params[:report_date]
if report_date && report_date.is_a?(Date)
#report_name = I18n.t('report_name_with_date', date: report_date.to_s)
else
#report_name = I18n.t('report_name')
end
If you want behaviour exactly as you have described, you'd need two yaml entries anyway, and you'd have extra convolution, and you'd be doing a I18n no-no by creating a string by concatenating two strings together, which assumes a fixed grammatical sentence structure (not to mention this drives translators up the wall):
report_name_with_date: My report%{on_date}
on_date: on %{date}
with code something like this:
report_date = params[:report_date]
if report_date && report_date.is_a?(Date)
on_date = I18n.t('on_date', date: report_date.to_s)
#report_name = I18n.t('report_name_with_date', on_date: " #{on_date}")
else
#report_name = I18n.t('report_name_with_date', on_date: nil)
end
So, in summary, I'd say go with two separate whole strings, like in the first example.
This is the way i did it!
First set my translation
I18n.t('my_translation', parameter: optional_parameter)
Check if value is nil
optional_parameter = value.nil? "" : "with an optional parameter which value is #{value}"
I18n.t('my_translation', parameter: optional_parameter)
if value is nil =>"This is my translation"
if value is 1 => "This is my translation with an optional parameter which value is 1"
If you're using a number as an optional argument, Rails provides a better way to handle it.
e.g.
invoice:
zero: "Great! You have no pending invoices."
one: "You have only 1 pending invoice."
other: "You have %{count} pending invoices."
>> t("invoice", count: 0)
=> Great! You have no pending invoices.
>> t("invoice", count: 1)
=> You have only 1 pending invoice.
>> t("invoice", count: 5)
=> You have 5 pending invoices.
I'm about to lose my mind due to a simple Rails where query. I simply cannot understand why it does work like 10 lines ago and does not after it. I could not figure out what might be causing the problem
#userID = Token.where(:tokenCode => #tokenReceived)
##init.tokenCode=#tokenReceived+"1" #randomize algorithm required!
#init.tokenCode=#codeGenerated=generate_activation_code()
if #userID.nil?
#newToken=Token.new
#newToken.tokenCode=#codeGenerated
else
#tokenToAdd = "12"
#newToken=Token.where(:userID => "1")
#if #newToken.nil?
#newToken.tokenCode="12"
#end
end
##newToken.save
#init.save
When I make a successful JSON request to 'http://localhost:3000/inits.json' it gives me a page with tons of erros but I think the main error among those are:
<h1>
NoMethodError
in InitsController#create
</h1>
<pre>undefined method `tokenCode=' for #<ActiveRecord::Relation:0x007fc43cb40b88></pre>
What could be the reason? Am I writing the where clause all wrong?
Edit: When I activate the if clause it works. I simply believe the #newToken object is null, however it is almost impossible for me to detect why. There is a data in my Token table with userID 1.
When you do:
#newToken=Token.where(:userID => "1")
You get an ActiveRecord::Relation, but you expect an object. So simply replace it with:
#newToken=Token.where(:userID => "1").first