Rails no implicit conversion of Symbol into Integer(rails) - ruby-on-rails

I am trying to save a data inside bookmark variable but it's throwing an error which is described in the title.Please Tell me what am I doing wrong I can't understand the error.
bookmarks = Bookmark.where(request_id: bookmarked_against_Request[:_id])
if bookmarks
bookmarks[:corsponding_requests] << request_bookmarked[:id]
else
bookmarks_new = Hash.new
bookmarks["owner_req"] = session[:user]
bookmarks["request_id"] = data
bookmarks["corsponding_requests"] = Array.new
bookmarks["corsponding_requests"] << request_bookmarked[:_id]
Bookmark.createBookmark(bookmarks)
end
PS:- I HAVE CHANGED BOOKMARKS TO BOOKMARKS_NEW IN THE ELSE BLOCK BUT IT STILL THROWING THE SAME ERROR

Try this:
bookmarks = Bookmark.where(request_id: bookmarked_against_Request[:_id])
if bookmarks
bookmarks.each { |bookmark| bookmark.update_attributes(corsponding_requests: request_bookmarked[:id] }
else
bookmark = Hash.new
bookmark["owner_req"] = session[:user]
bookmark["request_id"] = data
bookmark["corsponding_requests"] = Array.new
bookmark["corsponding_requests"] << request_bookmarked[:_id]
Bookmark.createBookmark(bookmark)
end

You can imagine bookmarks like array, and when you try bookmarks[:corsponding_requests] ruby "think", that you want acces to array element through integer index (for example like bookmarks[1]) but it can't convert symbol to integer and throw an error. Maybe, it helps you...

Related

Filterring ActiveRecord Relation...if there are no matches. (Null the active record relation)

I have a dashboard that allows for filtering of the results by different parameters. I build methods to filter the results by the given criteria. One area where I'm having trouble is if the previous line should null out the active record relation. Should I just put a bunch of if present? stat
def find_website_stats(options = {})
if options[:date_between].present?
start_date = options[:date_between].split(/-/).first.to_date
end_date = options[:date_between].split(/-/).last.to_date + 1
elsif options[:start_date].present?
start_date = options[:start_date].to_date
end_date = options[:end_date].to_date + 1 if options[:end_date].present?
end
contractor_name = options[:search_contractor] if options[:search_contractor].present?
distributor_name = options[:search_distributor] if options[:search_distributor].present?
distributor_ids = options[:with_distributor] if options[:with_distributor].present?
contractor_ids = options[:with_contractor] if options[:with_contractor].present?
with_country = options[:with_country] if options[:with_country].present?
with_state = options[:with_state] if options[:with_state].present?
search_city = options[:search_city] if options[:search_city].present?
web_stats = self.website_stats
if web_stats.present?
web_stats = web_stats.where(contractor_id: [*contractor_ids]) if contractor_ids.present?
if distributor_ids.present?
web_stat_ids = DistributorWebsiteStat.where(distributor_id: [*distributor_ids]).pluck(:website_stat_id)
web_stats = web_stats.where(id: [*web_stat_ids])
end
web_stats = web_stats.where(date_recorded: start_date..end_date) if start_date.present? && end_date.present?
web_stats = web_stats.with_country(with_country) if with_country.present?
web_stats = web_stats.with_state(with_state) if with_state.present?
web_stats = web_stats.search_city(search_city) if search_city.present?
#untested
if contractor_name.present?
searched_contractor_ids = Brand.search_contractor(contractor_name).pluck(:id)
web_stats = web_stats.where(contractor_id: [*searched_contractor_ids])
end
if distributor_name.present?
searched_distributor_ids = Brand.search_distributor(distributor_name).pluck(:id)
web_stat_ids = DistributorWebsiteStat.where(distributor_id: [*searched_distributor_ids])
web_stats = web_stats.where(id: [*web_stat_ids])
end
#end untested
end
web_stats
end
Where I'm specifically having a problem right now is the line that says if web_stat_ids.present?
So at first I grab all the website stats this object is associated with and then look to see if there are any for the given distributor.
If there is none for the given distributor web_stat_ids obviously returns nil
Then when I go to the line web_stats.where(id: [*web_stat_ids]) that's obviously going to return the same thing that I had before, rather than an empty active record relation, which is what I need it to be?
If I make this an empty array the next few statements with "where" won't work because it's an array and not an active record relation.
I know I can wrap this stuff in a bunch of if present? && statements...but I was wondering if there is a better solution to my problem?
In case anyone else is looking for this, found the answer from this SO post: How to return an empty ActiveRecord relation?
Model.none rails 4+

creating an array using find method in rails

input = {"color"=>["red"],"size"=>["s","l"]}
json_obj = [{"color":"red","id":"123","size":"s","name":"test"},
{"color":"yellow","id":"124","size":"s","name":"test"},
{"color":"red","id":"125","size":"l","name":"test"}]
Output should be
output["red_s"] = {"color":"red","id":"123","size":"s","name":"test"}
output["red_l"] = {"color":"red","id":"125","size":"l","name":"test"}
output is the combinations of the input and a find on the json_obj.
How to get the output in rails?
I have the below script to get the combinations ie.red_s and red_l,
ary = input.map {|k,v| [k].product v}
output = ary.shift.product(*ary).map {|a| Hash[a]}
And
output[red_s]=json_obj.find{|h| h["color"] == "red" and h["size"] == "S"}
I don't want to have any hardcodings in code like color and size as above.
I think this should get you close to what you want.
Note the "ticks" around your json array object (what you had is not valid ruby)
The other issue is you would have to figure a better way to create the output hash key.
require 'json'
input = {"color"=>["red"],"size"=>["s","l"]}
output = {}
json_obj = '[{"color":"red","id":"123","size":"s","name":"test"},
{"color":"yellow","id":"124","size":"s","name":"test"},
{"color":"red","id":"125","size":"l","name":"test"}]'
found = JSON.parse json_obj
input.each_key do |key|
found = found.select { |item| input[key].include?(item[key]) }
end
puts found
found.each do |item|
output_key = ""
input.each_key do |key|
output_key = "#{item[key]}_" + output_key
end
output["#{output_key}"] = item.to_json
end
puts output

TypeError: no implicit conversion of Symbol into Integer

I encounter a strange problem when trying to alter values from a Hash. I have the following setup:
myHash = {
company_name:"MyCompany",
street:"Mainstreet",
postcode:"1234",
city:"MyCity",
free_seats:"3"
}
def cleanup string
string.titleize
end
def format
output = Hash.new
myHash.each do |item|
item[:company_name] = cleanup(item[:company_name])
item[:street] = cleanup(item[:street])
output << item
end
end
When I execute this code I get: "TypeError: no implicit conversion of Symbol into Integer" although the output of item[:company_name] is the expected string. What am I doing wrong?
Your item variable holds Array instance (in [hash_key, hash_value] format), so it doesn't expect Symbol in [] method.
This is how you could do it using Hash#each:
def format(hash)
output = Hash.new
hash.each do |key, value|
output[key] = cleanup(value)
end
output
end
or, without this:
def format(hash)
output = hash.dup
output[:company_name] = cleanup(output[:company_name])
output[:street] = cleanup(output[:street])
output
end
This error shows up when you are treating an array or string as a Hash. In this line myHash.each do |item| you are assigning item to a two-element array [key, value], so item[:symbol] throws an error.
You probably meant this:
require 'active_support/core_ext' # for titleize
myHash = {company_name:"MyCompany", street:"Mainstreet", postcode:"1234", city:"MyCity", free_seats:"3"}
def cleanup string
string.titleize
end
def format(hash)
output = {}
output[:company_name] = cleanup(hash[:company_name])
output[:street] = cleanup(hash[:street])
output
end
format(myHash) # => {:company_name=>"My Company", :street=>"Mainstreet"}
Please read documentation on Hash#each
myHash.each{|item|..} is returning you array object for item iterative variable like the following :--
[:company_name, "MyCompany"]
[:street, "Mainstreet"]
[:postcode, "1234"]
[:city, "MyCity"]
[:free_seats, "3"]
You should do this:--
def format
output = Hash.new
myHash.each do |k, v|
output[k] = cleanup(v)
end
output
end
Ive come across this many times in my work, an easy work around that I found is to ask if the array element is a Hash by class.
if i.class == Hash
notation like i[:label] will work in this block and not throw that error
end

Rails :: Why the attribute change doesn't persist?

Controller:
#events = Event.all
#events.each { |e| e.user_subscribed = "someuser" }
#events.each { |e| puts "error" + e.user_subscribed }
I have attr_accessor :user_subscribed. but the error is can't convert nil into String as e.user_subscribed evaluates to nil.
I'm using mongoid on the backend.
edit: this works, but it just copies the whole array.
#events = #events.map do |e|
e.user_subscribed = "faaa"
e
end
If you're not saving the #events to the database, user_subscribed won't persist, unless you keep it in memory:
#events_with_subscription = #events.map { |e| e.user_subscribed = "someuser"; return e }
edited based on OP comments.
sounds like it might be better to just output Event.user_subscribed(current_user) directly in the view...but if you wanted to load up all that data before hand you could do:
#array_of_subscription_results = #Events.map{|e| e.user_subscribed(current_user,some,other,var,required) }
As long as user_subscribed returns the values you are interested in, thats what map will load into #array_of_subscription_results

ruby - writing an array to a hash without overwriting

I do the following
my_hash = Hash.new
my_hash[:children] = Array.new
I then have a function that calls itself a number of time each time writing to children
my_hash[:children] = my_replicating_function(some_values)
How do I write without overwriting data that is already written ?
This is what the entire function looks like
def self.build_structure(candidates, reports_id)
structure = Array.new
candidates.each do |candidate, index|
if candidate.reports_to == reports_id
structure = candidate
structure[:children] = Array.new
structure[:children] = build_structure(candidates, candidate.candidate_id)
end
end
structure
end
Maybe this:
structure[:children] << build_structure(candidates, candidate.candidate_id)
structure[:children] << build_structure(candidates, candidate.candidate_id)

Resources