Arel + Rails 4.2 causing problems (bindings being lost) - ruby-on-rails

We recently upgraded to Rails 4.2 from Rails 4.1 and are seeing problems with using Arel + Activerecord because we're getting this type of error:
ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR: bind message supplies 0 parameters, but prepared statement "" requires 8
Here's the code that is breaking:
customers = Customer.arel_table
ne_subquery = ImportLog.where(
importable_type: Customer.to_s,
importable_id: customers['id'],
remote_type: remote_type.to_s.singularize,
destination: 'hello'
).exists.not
first = Customer.where(ne_subquery).where(company_id: #company.id)
second = Customer.joins(:import_logs).merge(
ImportLog.where(
importable_type: Customer.to_s,
importable_id: customers['id'],
remote_type: remote_type.to_s.singularize,
status: 'pending',
destination: 'hello',
remote_id: nil
)
).where(company_id: #company.id)
Customer.from(
customers.create_table_alias(
first.union(second),
Customer.table_name
)
)
We figured out how to solve the first part of the query (running into the same rails bug of not having bindings) by moving the exists.not to be within Customer.where like so:
ne_subquery = ImportLog.where(
importable_type: Customer.to_s,
importable_id: customers['id'],
destination: 'hello'
)
first = Customer.where("NOT (EXISTS (#{ne_subquery.to_sql}))").where(company_id: #company.id)
This seemed to work but we ran into the same issue with this line of code:
first.union(second)
whenever we run this part of the query, the bindings get lost. first and second are both active record objects but as soon as we "union" them, they lose the bindings are become arel objects.
We tried cycling through the query and manually replacing the bindings but couldn't seem to get it working properly. What should we do instead?
EDIT:
We also tried extracting the bind values from first and second, and then manually replacing them in the arel object like so:
union.grep(Arel::Nodes::BindParam).each_with_index do |bp, i|
bv = bind_values[i]
bp.replace(Customer.connection.substitute_at(bv, i))
end
However, it fails because:
NoMethodError: undefined method `replace' for #<Arel::Nodes::BindParam:0x007f8aba6cc248>
This was a solution suggested in the rails github repo.

I know this question is a bit old, but the error sounded familiar. I had some notes and our solution in a repository, so I thought I'd share.
The error we were receiving was:
PG::ProtocolViolation: ERROR: bind message supplies 0 parameters, but
prepared statement "" requires 1
So as you can see, our situation is a bit different. We didn't have 8 bind values. However, our single bind value was still being clobbered. I changed the naming of things to keep it general.
first_level = Blog.all_comments
second_level = Comment.where(comment_id: first_level.select(:id))
third_level = Comment.where(comment_id: second_level.select(:id))
Blog.all_comments is where we have the single bind value. That's the piece we're losing.
union = first_level.union second_level
union2 = Comment.from(
Comment.arel_table.create_table_alias union, :comments
).union third_level
relation = Comment.from(Comment.arel_table.create_table_alias union2, :comments)
We created a union much like you except that we needed to union three different queries.
To get the lost bind values at this point, we did a simple assignment. In the end, this is a little simpler of a case than yours. However, it may be helpful.
relation.bind_values = first_level.bind_values
relation
By the way, here's the GitHub issue we found while working on this. It doesn't appear to have any updates since this question was posted though.

Related

Nesting extra Span in Pandoc filter disappears the image

I am currently working on massaging the HTML output of a Pandoc filter due to some annoying restrictions in the CMS that is the eventual beneficiary of my hard work.
My working filter (now with the obvious declarations) is as follows:
local List = require 'pandoc.List'
local Emph = pandoc.Emph
local Quoted = pandoc.Quoted
local Span = pandoc.Span
local Str = pandoc.Str
local Strong = pandoc.Strong
local image_base = "http://my.website.example/images/"
local image_author = "Someone Not Stigma"
function process_images(el)
el.src = el.src:gsub("^file:images/", image_base)
el.caption = {
Strong( Quoted( "DoubleQuote", el.caption ) ),
Str(" by "),
Emph(image_author)
}
return el
end
return {{Image = process_images}}
In the eventual HTML, this gives me a nice figure with img and figcaption element inside of it. Wonderful. Unfortunately, my CMS destroys the figcaption (like it tends to destroy other stuff), and as such I figured I'd wrap everything in an extra span so I can style that one instead.
function process_images(el)
el.src = el.src:gsub("^file:images/", image_base)
el.caption = {
Span(
{
Strong( Quoted( "DoubleQuote", el.caption ) ),
Str(" by "),
Emph(image_author)
},
{ class="img-caption" }
)
}
return el
end
And yet somehow, this causes Pandoc to completely delete the image from the resulting HTML.
I have tried replacing the table syntaxes with List({}) syntaxes, but that just gives me upvalue complaints. I looked at the manual, but for as far I can tell I am doing everything right.
What am I missing here?
I call pandoc as follows:
pandoc --from=markdown-tex_math_dollars "Content.pure.txt" --lua-filter=".\pandoc-filter.lua" --to=html5 --template=".\pandoc-template.txt" -o "Content.txt"
Extensions are .txt (because these files are not browser ready). The template being used is rather lengthy (there's a fair bit of YAML variables and related markup), but be assured: $body$ can be found in there.
I am not a wise man. Always update to the latest version before posting questions, folks.
I was running an older version of Pandoc (v2.6), and upgrading to v2.9.1.1 suddenly made the output appear again. That's a lot of versions released in the span of about a year!
(In my defense, my Pandoc-filter-fu is not particularly strong, so it makes sense to assume user error rather than program bug. Why is it that every time you assume bug, it is user error, and every time you assume user error, it is an outright bug?)

<ActiveRecord::QueryMethods::WhereChain error on a scope that was working

I've been running a piece of code for a while with success but it has just started throwing an error - we've altered the way data is going into the database but believe it's more likely a programming issue or I've altered it by mistake, but can't see where.
The issue appears to be caused form a scope, we're running Rails 4.2.2
The complete error is
undefined method `call' for
ActiveRecord::QueryMethods::WhereChain:0x007feb8f5c49f0> Did you mean? caller
app/controllers/orders_controller.rb:158:in `weekly_sales_report'
in my orders_controller line 158
#sales_this_week_bysales = Order.select("COUNT(order_id) AS nosales, AVG(net_amount) AS avgsale,SUM(sale_cost) AS sale_cost, SUM(net_amount) AS weeklysalestotal, owner_id AS salesman").sales.where.(date_of_sale: (#startdate .. #enddate)).with_salesman.group(:owner_id)
in my orders.rb model I have the following used scopes
scope :with_salesman, -> { joins(:pipe_records).where(pipe_records: {pipe_part_id: 1}).where.not(pipe_records: {owner_id: nil}) }
scope :sales, -> {where ("orders.order_ref <>'' and date_of_sale IS NOT NULL ")}
I re-wrote the scope to the below but still got the same error
scope :with_salesman, -> { joins(" INNER JOIN pipe_records ON pipe_records.order_id = orders.id WHERE pipe_records.pipe_part_id =1 AND pipe_records.owner_id <>'' ") }
I also removed the WHERE startdate criteria from the sales.where on 158 which returned a different error, but it appears the scope isn't passing correctly anymore or returning an error due to bad records??
I'm now unsure what is happening, I went back to my remotes and took a copy of the code from a couple of days ago and this also threw the same error, but it was working correctly. We've put a lot of new records in recently through a new form which bypasses and alters created at dates which may be to blame. I would appreciate any suggestions or fresh eyes.
Just remove the period between where and the parenthesis.
where.(date_of_sale: (#startdate..#enddate))
In ruby
receiver.()
is short hand for receiver.call() thus the error you are receiving
You probably want to remove that period after where:
where.(date_of_sale: (#startdate .. #enddate))

Lua - table won't insert from function

I have a Lua function where I build a table of value and attempt to add it to a global table with a named key.
The key name is pulled from the function arguments. Basically, it's a filename, and I'm pairing it up with data about the file.
Unfortunately, the global table always comes back nil. Here's my code: (let me know if you need to see more)
(Commented parts are other attempts, although many attempts have been deleted already)
Animator = Class{}
function Animator:init(atlasfile, stringatlasfriendlyname, totalanimationstates, numberofframesperstate, booleanstatictilesize)
-- Define the Animator's operation mode. Either static tile size or variable.
if booleanstatictilesize ~= false then
self.isTileSizeStatic = true
else
self.isTileSizeStatic = false
end
-- Define the total animation states (walking left, walking right, up down, etc.)
-- And then the total frames per state.
self.numAnimationStates = totalanimationstates or 1
self.numAnimationFrames = numberofframesperstate or 2
-- Assign the actual atlas file and give it a programmer-friendly name.
self.atlasname = stringatlasfriendlyname or removeFileExtension(atlasfile, 'animation')
generateAnimationQuads(atlasfile, self.atlasname, self.numAnimationStates, self.numAnimationFrames)
end
function generateAnimationQuads(atlasfile, atlasfriendlyname, states, frames)
spriteWidthDivider = atlasfile:getWidth() / frames
spriteHeightDivider = atlasfile:getHeight() / states
animationQuadArray = generateQuads(atlasfile, spriteWidthDivider, spriteHeightDivider)
animationSetValues = {atlasarray = animationQuadArray, width = spriteWidthDivider, height = spriteHeightDivider}
--gAnimationSets[#gAnimationSets+1] = atlasfriendlyname
gAnimationSets[atlasfriendlyname] = animationSetValues
--table.insert(gAnimationSets, atlasfriendlyname)
end
Note: when using print(atlasfriendlyname) and print(animationSetValues), neither are empty or nil. They both contain values.
For some reason, the line(s) that assign the key pair to gAnimationSets does not work.
gAnimationSets is defined a single time at the top of the program in main.lua, using
gAnimationSets = {}
Animator class is called during the init() function of a character class called Bug. And the Bug class is initialized in the init() function of StartState, which extends from BaseState, which simply defines dummy init(), enter(), update() etc. functions.
StartState is invoked in main.lua using the StateMachine class, where it is passed into StateMachine as a value of a global table declared in main.lua.
gAnimationSets is declared after the table of states and before invoking the state.
This is using the Love2D engine.
Sorry that I came here for help, I've been picking away at this for hours.
Edit: more testing.
Trying to print the animationQuadArray at the index gTextures['buganimation'] always returns nil. Huh?
Here's gTextures in Main.lua
gTextures = {
['background'] = love.graphics.newImage('graphics/background.png'),
['main'] = love.graphics.newImage('graphics/breakout.png'),
['arrows'] = love.graphics.newImage('graphics/arrows.png'),
['hearts'] = love.graphics.newImage('graphics/hearts.png'),
['particle'] = love.graphics.newImage('graphics/particle.png'),
['buganimation'] = love.graphics.newImage('graphics/buganimation.png')
}
Attempting to return gTextures['buganimation'] returns a file value as normal. It's not empty.
My brain is so fried right now I can't even remember why I came to edit this. I can't remember.
Global table in Main.lua, all other functions can't access it.
print(gTextures['buganimation']) works inside the function in question. So gTextures is absolutely accessible.
Table isn't empty. AnimationSetValues is not empty.
I'm adding second answer because both are correct in context.
I ended up switching IDE's to VS Code and now the original one works.
I was originally using Eclipse LDT with a Love2D interpreter and in that environment, my original answer is correct, but in VS Code, the original is also correct.
So Dimitry was right, they are equivalent, but something about my actual Eclipse setup was not allowing that syntax to work.
I switched to VS Code after I had another strange syntax problem with the interpreter where goto syntax was not recognized and gave a persistent error. The interpreter thought goto was the name of a variable.
So I switched, and now both things are fixed. I guess I just won't use LDT for now.
Solution: Lua syntax. Brain Fry Syndrome
I wrote:
animationSetValues = {atlasarray = animationQuadArray, width = spriteWidthDivider, height = spriteHeightDivider}
Should be:
animationSetValues = {['atlasfile']=atlasfile, ['atlasarray']=animationQuadArray, ['width']=spriteWidthDivider, ['height']=spriteHeightDivider}
Edit: I'm fully aware of how to use answers. This was posted here to reserve my spot for an answer so I could edit it later when I returned back home, which is exactly what I'm doing right now. I'll keep the old post for archival purposes.
Original:
I solved it. I apologize for not posting the solution right now. My brain is melted into gravy.
I will post it tomorrow. Just wanted to "answer" saying no need to help. Solved it.
Solution is basically, "oh it's just one of those Lua things". Wonderful. I'm having so much fun with this language - you can tell by my blank expression.
From the language without line endings or brackets, but forced print parentheses... ugh. I'm going back to C# when this class is done.

Rails: Where clause doesn't work in any condition

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

Nokogiri pull parser (Nokogiri::XML::Reader) issue with self closing tag

I have a huge XML(>400MB) containing products. Using a DOM parser is therefore excluded, so i tried to parse and process it using a pull parser. Below is a snippet from the each_product(&block) method where i iterate over the product list.
Basically, using a stack, i transform each <product> ... </product> node into a hash and process it.
while (reader.read)
case reader.node_type
#start element
when Nokogiri::XML::Node::ELEMENT_NODE
elem_name = reader.name.to_s
stack.push([elem_name, {}])
#text element
when Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE
stack.last[1] = reader.value
#end element
when Nokogiri::XML::Node::ELEMENT_DECL
return if stack.empty?
elem = stack.pop
parent = stack.last
if parent.nil?
yield(elem[1])
elem = nil
next
end
key = elem[0]
parent_childs = parent[1]
# ...
parent_childs[key] = elem[1]
end
The issue is on self-closing tags (EG <country/>), as i can not make the difference between a 'normal' and a 'self-closing' tag. They both are of type Nokogiri::XML::Node::ELEMENT_NODE and i am not able to find any other discriminator in the documentation.
Any ideas on how to solve this issue?
There is a feature request on project page regarding this issue (with the corresponding failing test).
Until it will be fixed and pushed into the current version, we'll stick with good'ol
input_text.gsub! /<([^<>]+)\/>/, '<\1></\1>'
Hey Vlad, well I am not a Nokogiri expert but I've done a test and saw that the self_closing?() method works fine on determining the self closing tags. Give it a try.
P.S. : I know this is an old post :P / the documentation is HERE

Resources