improper jbuilder syntax for output during API error handling - ruby-on-rails

The following is a json.jbuildermethod intended to respond to an API call.
if #error_code_98?
json.set! :chain_category do
json.set! :error, #error_98_messages
end
end
#error_code_99 = true when said errors arise.
error_98_messages is a concatenation of string that provide an indentifier with the nature of the error. They are accumulated as an array of items are handled by the API action.
When the error hits, the instance variable gets populated, but at the end of the action the return message this the following error
syntax error, unexpected tSYMBEG, expecting ':'
json.set! :chain_category do
I thought this was respecting the syntax for dynamic attribution, but that is mistaken. Where is the syntax off?

Related

setting conditional attributes for API connection

A method needs to instantiate a session with various attributes, some of which are optional
session = Checkout::Session.create({
locale: I18n.locale,
reference_id: id,
customer_email: #user_mail,
[...]
})
The last shown attribute, customer_email, is optional but it should not be generated if the value does not exist.
customer_email: #user_mail unless !#user_email,
logically hits a syntax error because an additional param (the comma) is being produced
syntax error, unexpected ',', expecting end
and thus the API expects another attribute.
(customer_email: #user_mail, unless !#user_email)
also fails as there is confusion over the parenthesis
syntax error, unexpected ')', expecting then or ';' or '\n'
How should this syntax be cast?
You need to extract the options hash into a variable and manipulate it before sending it to the Checkout::Session.create.
Something like this:
options = {
locale: I18n.locale,
reference_id: id
}
options[:customer_email] = #user_mail if #user_email
session = Checkout::Session.create(options)

Rails scope syntax issue

I am trying to define a scope whereby a field in a related object has a value of 1. It seems to throw an error when I do this:
scope :in_progress, ->{Submission.where(current_agent.agent_activities.last.Status: 1)}
Desired effect is to call all Submissions that have a status of "In progress" which has a hash value of 1.
Error:
SyntaxError (/Users/gbade/Desktop/RoR/Ottom8/app/models/submission.rb:16: syntax error, unexpected ':'
.agent_activities.last.Status: 1)}
^):

How to Rescue ActiveRecord::StatementInvalid Error

Does anyone know how to rescue this ActiveRecord::StatementInvalid error in rails? The console displays "PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer...". I've tried inserting a pry into the rescue block, but it's never called.
if (resource_params[:term].present?)
begin
key = resource_params[:term]
scope = scope.where("id = ? OR item_type = ? OR item_id = ? OR event = ? OR object ILIKE ?", key, key, key, key, "%#{key}%")
rescue
# handle error
end
end
Please note that I know how to prevent the error from occurring (i.e. need to convert the key to type integer for the id columns). But, I'm trying to understand why it never reaches the rescue block.
UPDATE: my initial post contained a syntax error (namely: rescue e => error) as others correctly pointed out. i'm still receiving the same error without the syntax error; i've update the code to remove the incorrect syntax.
This isn't the correct syntax for rescue:
rescue e => error
if I try and use this I get undefined local variable or method 'e'
The standard way to rescue a specific error class is to use:
rescue ActiveRecord::StatementInvalid => e
To do a "naked rescue" (which is often advised against), leave out the class name:
rescue => e
Note that in all these cases the => e can be left out if you don't need a variable pointing to the error object.
rescue ActiveRecord::StatementInvalid => e is the right syntax and should work fine, but also keep in mind that exception should actually be raised within that block.
rails executes a query when we actually try using its output(for example rendering page where we are displaying output of a query).

RSpec: Matching arguments for receive_message_chain

I'm trying to stub:
Thing.where(uuid: options['uuid']).first
Via:
allow(Thing).to receive_message_chain(:where, :first)
.with(uuid: thing_double.uuid)
.and_return(nil)
But this is returning:
#<Double (anonymous)> received :first with unexpected arguments
expected: ({:uuid=>123})
got: (no args)
Is there a different way I should be validating arguments for message chains?
It doesn't appear that you can use with in combination with receive_message_chain when the arguments pertain anything other than the final method. Thus the message:
#<Double (anonymous)> received :first with unexpected arguments
This makes sense -- how can RSpec know which method in the chain should receive the arguments?
To verify the argument expectation, don't stub the chain, just stub where
allow(Thing).to receive(:where).with(uuid: 1).and_return([])
expect(Thing.where(uuid: 1).first).to eq nil
Or omit the arguments:
allow(Thing).to receive_message_chain(:where, :first).and_return(nil)
expect(Thing.where(uuid: 1).first).to eq nil
receive_message_chain is not recommended IMO. From the docs:
you should consider any use of receive_message_chain a code smell
Here's how we addresses a similar situation:
expect(Theme).to receive(:scoped).and_return(double('scope').tap do |scope|
expect(scope).to receive(:includes).with(:categories).and_return scope
expect(scope).to receive(:where).with(categories: { parent_id: '1'}).and_return scope
expect(scope).to receive(:order).with('themes.updated_at DESC').and_return scope
expect(scope).to receive(:offset).with(10).and_return scope
expect(scope).to receive(:limit).with(10000)
end)
In recent months, by pure accident, I discovered that you can actually chain your "with" invocation in the order of the message chain. Thus, the previous example, becomes this:
expect(Theme).to receive_message_chain(:scoped, :includes, :where, :order, :offset, :limit).with(no_args).with(:categories).with(categories: { parent_id: '1'}).with('themes.updated_at DESC').with(10).with(10000)
It's sometimes error prone (I'll intermittently get an error saying "wrong number of arguments (0 for 1+)"; although this seems to only happen when performing multiple receive_message_chains in a single test), but you can also opt for chaining your "with" methods thus:
expect(User).to receive_message_chain(:where, :order).with(active: true).with('name ASC')

ruby raise exception on iterator

The following function might return a null value hence I want to use the exception flow. Can someone direct me to the correct way to do it because right now I am getting the error.
syntax error, unexpected keyword_else, expecting keyword_end else
def value_from_table1(field, key)
begin
##connection.query("SELECT #{field} FROM table1 Where key = #{key} ").each do |row|
rescue Exception=>e
puts e
else
return row[field]
end
end
end
You are passing a block to Enumerator#each which introduces a new scope, so you need to put begin as a start of exception block inside.
If you also need handle exceptions of ##connection.query, just put rescue after do-end block of .each. begin is implicit at start of method's body.
First, rescuing from Exception is always a bad idea, see Why is it a bad style to `rescue Exception => e` in Ruby? for details.
Second a begin rescue block always has to have a closing end, else is only possible after an if before
begin
# ...
rescue StandardError => e
# ...
end
Third as already said by Justin Turner in the comment, just passing a value to the DB like that makes it prone to SQL injections. Is there any reason you don't use ActiveRecord but want direct DB access?
Overall there are so many issues with this short piece of code, I would suggest to read http://guides.rubyonrails.org/ to better understand what is going on.

Resources