How to pass Proc as block with additional arguments? - ruby-on-rails

Let's say, I have the following code:
File.open("text.txt", "w") do |f|
f << "hello"
end
How do I pass the block if it is given as a Proc?
I tried:
log_to_file = Proc.new { |f| f << "hello"}
File.open("text.txt", "w")(&log_to_file)
But this gives me the error:
syntax error, unexpected '(', expecting keyword_end)

Pass it as the last argument
File.open("text.txt", "w", &log_to_file)

Related

ruby on rails: multiple conditions in select array with hashes

This line works:
f = a.select{ |g| g['done']== 'false' }.select{ |g| g['subject'].include? "send" }.pluck('id','done','subject')
But this line
f = a.select{ |g| g['done']== 'false' && g['subject'].include? 'send' }
Does not. I get a
syntax error, unexpected '}', expecting `end'
... g['subject'].include? 'send' }
...
^
What's wrong with the code?

Rubocop Lint/Void: Literal used in void context

I have been running rubocop and encountered a Lint/Void: Literal used in void context offence.
the following code:
routes_and_postcodes.each do |hash|
2..7.each do |i|
route = Route.where(name: hash[:route]).first if postcode.delete(" ").first(i) == hash[:postcode].delete(" ")
end
end
I have read the docs, but still cant understand what the issue is.
In context, the full code is here:
def choose_own_van_route(postcode)
route = nil
routes_and_postcodes = []
Route.all.each do |r|
route_postcodes = r.postcode_array
route_postcodes.each do |pc|
routes_and_postcodes << { postcode: pc, route: r.name }
end
end
routes_and_postcodes.each do |hash|
2..7.each do |i|
route = Route.where(name: hash[:route]).first if postcode.delete(" ").first(i) == hash[:postcode].delete(" ")
end
end
route || Route.create(cut_off_time_mins_since_midnight: 0, name: "BLANK ROUTE HAD TO BE ASSIGNED")
end
Thanks
2..7.each do |i|
# ...
end
...is invalid code!! Have you tried running it? You'll see the following error:
NoMethodError: undefined method `each' for 7:Integer
To fix this, you need to define the Range in brackets:
(2..7).each do |i|
# ...
end
The rubocop error is in relation to this: Since if there were an each method defined on Integer (there isn't, but rubocop doesn't know that), then the code would be valid but the 2..<something> range definition would serve no purpose; it's a literal with a void context.

PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer

I am doing a "IN" query using prepared statements on rails. I am getting PG::InvalidTextRepresentation error.
code :
def mark_ineligible(match_ids)
ids = match_ids.join(", ")
result = epr("mark_matches_as_ineligible",
"UPDATE matches SET is_eligibile=false WHERE id IN ( $1 )",
[ids])
end
def epr(statementname, statement, params)
connection = ActiveRecord::Base.connection.raw_connection
begin
result = connection.exec_prepared(statementname, params)
return result
rescue PG::InvalidSqlStatementName => e
begin
connection.prepare(statementname, statement)
rescue PG::DuplicatePstatement => e
# ignore since the prepared statement already exists
end
result = connection.exec_prepared(statementname, params)
return result
end
end
trying to invoke this using :
match_ids = [42, 43]
mark_ineligible match_ids
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "42, 43"
from (irb):24:in `exec_prepared'
from (irb):24:in `rescue in epr'
from (irb):15:in `epr'
from (irb):8:in `mark_ineligible'
from (irb):35
Please help here. I want to know why I am getting this errors and how to fix it.
Thanks,
mark_ineligible should look as follows:
def mark_ineligible(match_ids)
result = epr("mark_matches_as_ineligible",
"UPDATE matches SET is_eligibile=false WHERE id IN ( $1 )", match_ids)
end
And when you call mark_ineligible, pass an array as argument:
mark_ineligible(match_ids) #=>match_ids = [42,43]

Are Parentheses Still Optional in Ruby?

If I run, per the docs
a = [:code]
a.collect { |x| x.to_s } # => ["code"]
However if I run
a = [:code]
a.collect({ |x| x.to_s }) # => SyntaxError
As far as I know, ruby has optional parens. How is my syntax getting screwed up here? This is an even bigger problem for me because I want to chain another function after this one, so I require the parens.
You aren't passing the block as a parameter to the parenthesis.
a.collect { |x| x.to_s }
is the same as
a.collect() {|x| x.to_s }
is the same as
a.collect() do |x|
x.to_s
end
And all of that is fairly close to this as well:
block = -> (x) {x.to_s} # Shortcut 'stabby' syntax for lambda{|x| x.to_s}
a.collect(&block) # Or a.collect &block

Ruby on Rails array delete_if block, string is "missing translation: no key" inside but fine outside

My problem is that the print t inside the delete_if block prints 'translation missing: en.no key'
This is strange. The error message in the browser shows me my pages parameters.
Here is what is says for tutor_id:
"tutor_id"=>["1", "2"].
I also tried the following inside the block to make sure it was right, and it did indeed return String.
print t.class # => returns 'String'
Also making a call to the following inside the block yields an error
Integer(t) # => yields error: invalid value for Integer(): "translation missing: en.no key"
Likewise, a call to .to_i is not helpful. It always returns 0. Note: this is the behavior o any non-numerical string such as 'hello'.to_s
print t.to_i # always prints '0'
The following is the troublesome code:
#get an array of all tutors' IDs
tutorIds = params[:tutor_id]
tutorIds.delete_if { [t]
print t
Schedule.exists?(["tutor_id = ?", Integer(t)])
}
Update I left out a bit of information so if the delete_if block is
tutorIds.delete_if { [t]
print t
Schedule.exists?(["tutor_id = ?", t ])
}
The error I get is:
PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "translation missing: en.no key" LINE 1: ...ECT 1 AS one FROM "schedules" WHERE (tutor_id = 'translati... ^ : SELECT 1 AS one FROM "schedules" WHERE (tutor_id = 'translation missing: en.no key') LIMIT 1
Well it was right under my nose. Such a simple mistake. Notice the [] -> ||
tutorIds.delete_if { [t]
print t
Schedule.exists?(["tutor_id = ?", t ])}
Should have been
tutorIds.delete_if { |t|
print t
Schedule.exists?(["tutor_id = ?", t ])}
Can you try
Schedule.where("tutor_id = ?", t.to_i).exists?
instead?

Resources