I have a psql table with a column named params that contains a hash. Below is my scenario:
When I do the following query...
game = Game.select('games.params').where(id: 123).first
... it prints out...
p game.params.class # => !ruby/class 'ActiveSupport::HashWithIndifferentAccess
Now I can go ahead an access values inside the returned hash normally.
But when I give the column name an alias in my query (here is my problem)...
game = Game.select('games.params as parameters').where(id: 123).first
... it prints out...
p game.parameters.class # => !ruby/class 'String'
I need to be able to change the column name in my query and then access the values inside the hash, but when I try to do p game[:time] it's being treated as a string.
I'm new to Ruby and Ruby on Rails, so this might be very simple to figure out but I am at a dead end right now.
What about this query:
g = Game.find 123
g.params
Related
I am attempting to order by a column of type "character varying []" and cast it to an integer[] while sorting (instead of using the default ASCII comparison sort). I am using a Postgresql database.
I've found that the following query works as expected:
select <col> from <table> order by <col>::integer[] desc
Unfortunately, when I attempt to programmatically do this in rails it is adding quotes around the column and casting suffix. This results in it thinking "::integer[]" is part of the column name - and of course there is no such column. Thus the query fails.
Here is the rails code:
scope.order([ '<col>::integer[]', 'desc', 'NULLS LAST' ].join(' '))
And this is the query it produces:
select <col> from <table> order by "<table>"."<col>::integer[]" desc
How can I implement this properly with rails?
Thanks to #engineersmnky comment, I found the solution that I need in my code.
In the code I'm actually processing an array of columns (and directions) to sort by. It turns out the solution was indeed to use the Arel.sql() function to process the order by parameters prior to calling scope.order(), with the end result looking something like this:
def sort(scope, sorts)
str = \
sorts.map |sort| do
col = get_sort_column_alias(sort[0])
dir = sort[1]
nullpos = (dir == 'asc') ? 'FIRST' : 'LAST'
"#{col} #{dir} NULL #{nullpos}"
end
scope.order(Arel.sql(str))
end
def get_sort_column_alias(col)
case col
when 'target' then 'target::integer[]'
...
else col
end
end
I have a form that has nested field (habtm and accepts_nested_attributes_for). That form contains with a field "keywords", that autocompletes keywords that come from a postgresql table.
All that works well. This is in params :
"acte"=>{"biblio_id"=>"1", "keywords"=>{"keywords"=>"judge, ordeal, "}
What I now need to do is take those keywords and get their keywords_id out of the table keywords. Those id must be added to the join table.
I'm doing this :
q = params[:acte][:keywords].fetch(:keywords).split(",")
a = q.map {|e| Keyword.find_by keyword: e }
As per the guides, find_by returns only the first matching field. I guess I would need to use find_each but I'm not certain about that and I can't get it to word. I have tried this:
q = params[:acte][:motclefs].fetch(:motclefs).split(",")
a = Array.new
Motclef.where(motcle: q).find_each do |mot|
a << mot.id
end
This also finds only the first result like : [251].
What I'm looking to get is something like [1453, 252, 654]
thanks !
Putting find_by in a loop means you will be executing a separate SQL query for each SQL keyword.
You can instead just get all the ids in a single SQL call by doing keyword in.
After you do q = params[:acte][:keywords].fetch(:keywords).split(","), your q will be an array of keywords. So q will be ["judge", " ordeal"].
You can simply do Keyword.where(keyword: q).select(:id) which will generate a query like SELECT keywords.id FROM keywords where keyword in ('judge', 'ordeal').
I'm trying to get a record in DB by having these two lines in one of my models:
a = Arel::Table.new(:receivers)
e = Receiver.where(a[:name].matches('%afsane%'))
In my receivers table I have a row in which the name column equals to "afsane".I want to have that row's id in my model.
but by printing the e in my model I've got this :
"========#<Receiver::ActiveRecord_Relation:0x0056094261eff8>============"
which gives the relation number but no params.
When I run them in rails console I got this response:
#<ActiveRecord::Relation [#<Receiver id: 2, name: "afsane", created_at: "2016-09-27 09:24:16", updated_at: "2016-10-09 10:10:02">]>
I managed to have this in my model But I couldn't .
ps:Using Rails 5.
Have any Ideas ?
I'm not sure what the variable a looks like but the variable e is a collection.
where returns a collection which means you will have to iterate through e in order to pull out some data.
Like so:
e.each do |data|
data.name
end
If you want to return only 1 result then you can simply do the following:
e = Receiver.where(a[:name].matches('%afsane%')).limit(1)
Note: I've kept the answer simple but there are more elegant solutions to this so I recommend you reading the ActiveRecord Rails Guides
I have a Node object that has an attribute called cached_user_tag_list, that stores a comma separated list of email addresses as a string like this:
[3] pry(main)> n.cached_user_tag_list
=> "gerry#test.com, danny#test.com"
If I set a local variable to be one of those email addresses, I can use ruby's include? string method to find if a node contains that email address. Here is an illustration:
[6] pry(main)> g = "gerry#test.com"
=> "gerry#test.com"
[8] pry(main)> n.cached_user_tag_list.include? g
=> true
What I would like to do, is create a Scope on my Node class/model that will accept g and search against the column/attribute cached_user_tag_list for all the Nodes in my DB and return a collection or AR Relation of all of those Nodes that contain that email address stored in the variable g within their string at cached_user_tag_list.
How do I do this?
Edit 1
I tried Node.where('cached_user_tag_list.include?'(g)), but that didn't work.
If it's just plain old string column with comma separated values, you can do something like this:
scope :find_nodes_which_include, ->(email) { |email| where("cache_user_tag_list like ?", "%#{email}%") }
I'm beginning to learn RoR, but i've a problem which i don't understand. With Product.find :all returns all the records from DB. But if i want to find_by_gender(1) (or even 2) it returns a nil, i'm certain that the db contains products with a gender
My code controller:
gender = params[:gender].to_i
#search_results = Product.find_by_gender(gender)
this returns a nill,
What am i doing wrong?
Greetings!
find_by_... returns either first record or nil if none found, find_all_by_... returns all records that match (or empty array if none). In your case nil means no records found with gender = 1.
Verify your data first!
Look at some sample records:
Do something like:
Product.all(:limit => 5).each {|product| product.id.to_s + product.gender}
or go into sql
sql> select id, gender from products where id < 6;
If you are to verify what the gender values are you can then create named scopes in your model for those conditions, e.g. (rails3)
(Product Model - app/models/product.rb)
scope :male where(:gender) = male_value # i.e. 1 or 'M' or 'Male' or whatever
scope :female where(:gender) = female_value # i.e. '2' or 'F' or whatever
Which will then you let write Products.male or Products.female !
Final note - should gender be in your users table? , or is this for male / female specific products?
in rails console execute
Product.pluck(:gender)
And u will know that values does it have in AR(i think true and false), so u have to use query Product.find_by_gender(true)