I'm getting this error:
TypeError in Properties#show
At line #67 in /Users/taylor/Pro/rentroll_analysis/app/views/properties/show.html.erb, where this exception is raised:
can't convert Array into Integer
This is the extracted source around line #67:
64: <td><%=u.unit_number%></td>
65: <td><%=u.unit_type%></td>
66: <td><%=number_to_currency(u.market_rent - u.current_rent)%></td>
67: <td><%=number_to_currency(u.market_rent - u.current_rent)*(session[:assumptions]= [:spread_x])%></td>
68:
69: </tr>
70: <%end%>
When running this:
def setup_assumptions
if session[:assumptions].nil?
session[:assumptions]=[:min_spread=>400,:spread_x=>10]
end
end
I'm sure it's relatively simple but I can't figure it out.
If you're trying to set it to a map, use a map (curly braces) not an array (square brackets):
session[:assumptions] = { :min_spread => 400, :spread_x => 10 }
Otherwise you're setting session[:assumptions] to an array with a hash in it.
Also, what is your goal here?
number_to_currency(u.market_rent - u.current_rent) * (session[:assumptions]= [:spread_x])
I think you mean:
number_to_currency(u.market_rent - u.current_rent) * session[:assumptions][:spread_x]
When you save something to your session it saves it as a string, so when you're pulling something back from the session and want to perform Integer methods on it, you'll likely have to specify that it's an integer.
Doing something like: session[:assumptions][:spread_x].to_i to use your session content as an integer. Also, please note I think you have an errant = in your original code.
Lastly, you might not run into this, but I've sometimes had trouble using nested symbols in session variables. As in session[:assumptions][:spread_x]. I've sometimes had to change this to something like session[:assumptions]['spread_x'] and call the nested variable with a string instead.
Good luck!
Related
I have one variable with number and text concatenated (e.g. "[79511]Rocket"). If this variable does contains numbers inside the brackets, I must store then (numbers only) in one column of my table. I'm validating this with the below code:
enterprise_id = "[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/) rescue nil
When I test in with Puts, it works as 79511, fine.
But then when I run the code to insert into database like below:
enterprise_id = "[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/) rescue nil
insert_ds = DB["INSERT INTO pd_deals ( enterprise_id ) VALUES (?)", enterprise_id]
insert_ds.insert
The target column is Integer type in table.
It throws an error:
/home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1252:in `literal_other_append': can't express #<MatchData "79511" 1:"1"> as a SQL literal (Sequel::Error)
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:108:in `literal_append'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:673:in `block in placeholder_literal_string_sql_append'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:670:in `loop'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:670:in `placeholder_literal_string_sql_append'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/sql.rb:109:in `to_s_append'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1214:in `literal_expression_append'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:86:in `literal_append'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:345:in `literal'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1534:in `static_sql'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:23:in `insert_sql'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/actions.rb:334:in `insert'
from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/adapters/shared/postgres.rb:1355:in `insert'
from tt.rb:12:in `<main>'
I'm doing this way because I need to extract a number from a string. Any hint there? Is there any way better?
If you execute:
"[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/)
in irb, you'll see:
=> #<MatchData "79511" 1:"1">
because String#match returns a MatchData instance and calling inspect on a MatchData gives you #<MatchData ...>. If you puts that value:
puts "[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/)
you'll see 79511 because puts calls to_s on its arguments to convert them to strings.
Sequel won't call to_s, it will try to figure out how to translate the argument to something the database understands on its own and it doesn't know what to do with a MatchData instance, hence the:
can't express #<MatchData "79511" 1:"1"> as a SQL literal
error.
You could call to_s yourself:
DB["INSERT INTO pd_deals ( enterprise_id ) VALUES (?)", enterprise_id.to_s.presence]
or use the MatchData#[] method:
DB["...", enterprise_id ? enterise_id[0] : nil]
or even use String#[] as Cary Swoveland suggests:
enterprise_id = "[79511]Rocket"[/(?<=\[)\d+(?=\])/]
DB["...", enterprise_id.presence]
I'm not that familiar with Sequel so you might need some to_i calls in there to convert the '79511' strings to 79511 numbers.
I've a piece of code in my product model where I assign values to columns by fetching from s3. The column names includes a counter "i" as well -
The 3 sample column names are -
pic1_file_name
pic2_file_name
pic3_file_name
The problematic code is -
prod = Product.find(id)
i=1
s3 = AWS::S3.new
bucket=s3.buckets['bucket_name']
bucket.objects.each do |obj|
prod.("pic"+"#{i}".to_s+"_file_name")=obj.key[45..1]
# the above line give a syntax error, unexpected '=', expecting end-of-input
prod.("pic"+"#{i}".to_s+"_file_name").to_sym = obj.key[45..-1]
# The above line gives an error undefined method `call' for #<Product:0x7773f18>
prod.send("pic"+"#{i}".to_s+"_file_name")=obj.key[45..-1]
# The above gives syntax error, unexpected '=', expecting end-of-input
i+=1
end
prod.save
Could you please advise as to how should I structure my column name with a variable so that I can assign a value to it without having to type 15 separate columns every time.
Any pointers will be appreciated.
Thanks in advance!
You almost got the last one right. You see, when doing
obj.pic1_file_name = 'foo'
you're actually calling method pic1_file_name=, not pic1_file_name. That line is equivalent to this:
obj.pic1_file_name=('foo')
With that in mind, your last line becomes
prod.send("pic#{i}_file_name=", obj.key[45..-1])
You can use the send method to call a method from a string:
prod.send("pic#{i}_file_name") # to read
prod.send("pic#{i}_file_name=", obj.key[45..-1]) # to assign
I have the following hash. Using ruby, I want to get the value of "runs". I can't figure out how to do it. If I do my_hash['entries'], I can dig down that far. If I take that value and dig down lower, I get this error:
no implicit conversion of String into Integer:
{"id"=>2582, "entries"=>[{"id"=>"7", "runs"=>[{"id"=>2588, ...
Assuming that you want to lookup values by id, Array#detect comes to the rescue:
h = {"id"=>2582, "entries"=>[{"id"=>"7", "runs"=>[{"id"=>2588}]}]}
# ⇓⇓⇓⇓⇓⇓⇓ lookup element with id = 7
h['entries'].detect { |e| e['id'] == 7 }['runs']
.detect { |e| e['id'] == 2588 }
#⇒ { "id" => 2588 }
As you have an array inside the entries so you can access it using an index like this:
my_hash["entries"][0]["runs"]
You need to follow the same for accessing values inside the runs as it is also an array.
Hope this helps.
I'm not sure about your hash, as it's incomplete. So , guessing you have multiple run values like:
hash = {"id"=>2582, "entries"=>[{"id"=>"7", "runs"=>[{"id"=>2588}]},
{"id"=>"8", "runs"=>[{"id"=>2589}]},
{"id"=>"9", "runs"=>[{"id"=>2590}]}]}
Then, you can do
hash["entries"].map{|entry| entry["runs"]}
OUTPUT
[[{"id"=>2588}], [{"id"=>2589}], [{"id"=>2590}]]
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
I have an array of hashes. Each entry looks like this:
- !map:Hashie::Mash
name: Connor H Peters
id: "506253404"
I'm trying to create a second array, which contains just the id values.
["506253404"]
This is how I'm doing it
second_array = first_array.map { |hash| hash[:id] }
But I'm getting this error
TypeError in PagesController#home
can't convert Symbol into Integer
If I try
second_array = first_array.map { |hash| hash["id"] }
I get
TypeError in PagesController#home
can't convert String into Integer
What am I doing wrong? Thanks for reading.
You're using Hashie, which isn't the same as Hash from ruby core. Looking at the Hashie github repo, it seems that you can access hash keys as methods:
first_array.map { |hash| hash.id }
Try this out and see if that works--make sure that it doesn't return the object_id. As such, you may want to double-check by doing first_array.map { |hash| hash.name } to see if you're really accessing the right data.
Then, provided it's correct, you can use a proc to get the id (but with a bit more brevity):
first_array.map(&:id)
This sounds like inside the map block that hash is not actually a hashie - it's an array for some reason.
The result is that the [] method is actually an array accessor method and requires an integer. Eg. hash[0] would be valid, but not hash["id"].
You could try:
first_array.flatten.map{|hash| hash.id}
which would ensure that if you do have any nested arrays that nesting is removed.
Or perhaps
first_array.map{|hash| hash.id if hash.respond_to?(:id)}
But either way you may end up with unexpected behaviour.