I am new to Ruby and RoR.
I have a class method that looks like this:
def self.show_all_expired
puts "\r\n COUNT: #{self.expired.all.count}\r\n"
self.expired.all do |s|
puts "\r\n COUNT: #{s}\r\n"
end
puts "\r\nEND\r\n"
end
When I run it from the console I get this output:
As you can see the subscriptions collection is not iterated and the block body is not entered at all. But the count of the query is 31, so there must be records. Why do block is not executed?
Looking at the docs you can see that all doesn't expect a block. It just returns the ActiveRecord::Relation scope object.
Instead, you want to use each which calls the given block once for each element in row collection:
self.expired.each do |s|
puts "\r\n Subscription: #{s.inspect}\r\n"
end
Or find_each if you are dealing with a larger number of records.
Related
I am getting undefined method #merge however #merge method works good in the second block. What's wrong with Block 1?
# Block 1
network_posts = []
#networks.each do |network|
network_posts << network.posts.as_json.merge('pic' => network.pic.url)
end
# Block 2
network = []
#networks.each do |network|
network << network.as_json.merge('pic' => network.pic.url)
end
The as_json method is not obligated to return a Hash. It can return anything it wants, a string, a number, a boolean value, or even, as in this case, an array. Assuming it supports merge is a mistake.
Since this appears to be operating on a collection (network.posts) that will be an array. Merging that in isn't practical. You could merge in on each record's as_json result:
network.posts.map do |post|
post.as_json.merge(...)
end
I have two arrays containing strings. I'm trying to iterate through both arrays with nested .each do loops to see if any elements in the first array have a substring of any of the elements in the second array. I'm using .include? within the nested loops to check this. I want the result to be the string printed the number of times it matches an element in partials.
This is the method that isn't working
def orphanCheck(partials, partials1, duplicatesArray)
partials1.each do |i|
partials.each do |j|
if i.include?(j)
duplicatesArray.push(i)
end
end
end
end
I'm using this as a helper method to define partials and partials1
def manipulate(monthEmails, todayEmails, partials, partials1)
monthEmails.each do |i|
email = EmailAddress.new(i.to_s)
partials.push(email.host_name.to_s)
end
todayEmails.each do |j|
todaySignup = j.to_s.slice(11, 100)
partials1.push(todaySignup)
end
end
And then I'm calling the two with the following
manipulate(allUnique, todayEmails, partials, partials1)
orphanCheck(partials, partials1, duplicatesArray)
#puts duplicatesArray
duplicatesArray is printing some strings that shouldn't be matches and it's printing some strings more times than I want. For example, gmail.com isn't in partials at all but me#gmail.com, which is in partials1 once, is being pushed to duplicatesArray three times. If yahoo.com is in partials three times, then I would want me#yahoo.com (from partials1) to be pushed to duplicatesArray three times, for example.
To be sure you could be doing:
partials1.each do |i|
i_ups=i.split('#')[-1]
partials.each do |j|
if i_ups===j
duplicatesArray.push(i)
break
end
end
end
If I understood correctly (partials is only the host part of the email provider and partials1 is the full email address)
A better solution that should give you a correct duplicatesArray would be:
partials1.each do |email_address|
email_host = email_address.split("#").last
duplicatesArray.push(email_address) if partials.include?(email_host)
end
I have a Model user with the following method:
def number_with_hyphen
number&.insert(8, "-")
end
When I run it several times in my tests I get the following output:
users(:default).number_with_hyphen
"340909-1234"
(byebug) users(:default).number_with_hyphen
"340909--1234"
(byebug) users(:default).number_with_hyphen
"340909---1234"
(byebug) users(:default).number_with_hyphen
"340909----1234"
It changes the number ?Here are the docs https://apidock.com/ruby/v1_9_3_392/String/insert
When I restructure my method to:
def number_with_hyphen
"#{number}".insert(8, "-") if number
end
If works like expected. The output stays the same!
How would you structure the code, how would you perform the insert?
which method should I use instead. Thanks
If you're using the insert method, which in the documentation explicitly states "modifies str", then you will need to avoid doing this twice, rendering it idempotent, or use another method that doesn't mangle data.
One way is a simple regular expression to extract the components you're interested in, ignoring any dash already present:
def number_with_hyphen
if (m = number.match(/\A(\d{8})\-?(\d+)\z/))
[ m[1], m[2] ].join('-')
else
number
end
end
That ends up being really safe. If modified to accept an argument, you can test this:
number = '123456781234'
number_with_hyphen(number)
# => "12345678-1234"
number
# => "123456781234"
number_with_hyphen(number_with_hyphen(number))
# => "12345678-1234"
number_with_hyphen('1234')
# => "1234"
Calling it twice doesn't mangle anything, and any non-conforming data is sent through as-is.
Do a clone of the string:
"#{number}".clone.insert(8, '-')
I would like to create a Capybara method for reading the contents of a table, that takes a variable number of parameters and iterates through the parameters.
Here is the method I have:
Then /^I should see a table record with "(.*?)", "(.*?)", "(.*?)"$/ do |invisible, name, address, phone|
rows = page.all(".table-bordered tr")
expect(rows.any? { |record| record.has_content? name }).to be_true
rows.each do |record|
if record.has_content? name
expect(record.has_content? address).to be_true
expect(record.has_content? phone).to be_true
end
end
end
I'm using the same CSS table structure to create tables with much larger numbers of columns elsewhere in the program. So whether the table has 3 columns or 12, I'd like to be able to use the same method so I don't write awkward code.
How can I assign a variable number of parameters and loop through each parameter in Capybara?
def assert_my_table(name, *row_data)
# It will be much faster than looping through all rows
row = page.find(:xpath, "//*[#class='table-bordered']//tr[./td='#{name}']")
# retrive row contents only once (again, it will be faster than retrieving it again for each of the columns you want to assert)
row_text = row.text
row_data.each do |text|
expect(row_text).to include(text)
end
end
assert_my_table(name, address, phone)
The following code:
User.all.each {|u| puts u.id}
Prints out all the fields for all records.
How can I change it to only print the id field?
I was unable to replicate this behavior but if you are looking at this in console you may be mistaking the fact that #each returns self (and self, a big array of User objects, is then inspected) for the call to each printing all fields. Can you instead run User.all.each {|u| puts u.id}; nil to have the console return nil after the each and see if the behavior persists?
If you run puts u, does it give a hash or an object? If hash, then use puts u[:id] or puts u['id'] rather than puts u.id.
If you are running this irb or rails console, it should print out just the IDs but then the return from your code is the set of users which the console will then print out. Scroll up and you will see the output you expect followed by the print out of all the user objects with full details.