Say I have two tables xs and ys in the database; both xs, ys have two columns id, name, and several rows: where for both tables the first row has entries
id = 1, name = "John".
Now in rails,
X.find(1)
and
Y.find(1)
returns the same hash:
{id: 1, name: "John"}
Now both
X.find(1)
and
Y.find(1)
has method destroy, which should not be a standard ruby hash method. I had to make myself content with the idea that rails somehow provided these hashes with this method.
But how
{id: 1, name: "John"}.destroy
knows which of the tables xs, ys should have its first row destroyed?
Related
i'm using neo4j. what i'd like to do is to create a root node for search result and to create relationships from root node to search result nodes. and I'd like to set incremental number to each relationship's property.
if possible, with one query.
Sorry for not explaining enough.
This is what I'd like to do.
Any more concise way?
// create test data
WITH RANGE(0, 99) AS indexes,
['Paul', 'Bley', 'Bill', 'Evans', 'Robert', 'Glasper', 'Chihiro', 'Yamanaka', 'Fred', 'Hersch'] AS names
UNWIND indexes AS index
CREATE (p:Person { index: index, name: (names[index%10] + toString(index)) });
// create 'Results' node with relationships to search result 'Person' nodes.
// 'SEARCH_RESULT' relationships have 'order' and 'orderBy' properties.
CREATE(x:Results{ts: TIMESTAMP()})
WITH x
MATCH(p:Person)
WHERE p.name contains '1'
MERGE(x)-[r:SEARCH_RESULT]->(p)
WITH x, r, p
MATCH (x)-[r]->(p)
WITH x, r, p
ORDER BY p.name desc
WITH RANGE(0, COUNT(r)-1) AS indexes, COLLECT(r) AS rels
UNWIND indexes AS i
SET (rels[i]).order = i
SET (rels[i]).orderBy = 'name'
RETURN rels;
// validate
MATCH(x:Results)-[r:SEARCH_RESULT]->(p:Person)
RETURN r, p.name ORDER BY r.order;
I have two models, both associated with each other through has_many through.
I can query the model and filter based on its associated records:
Car.includes(:equipment).where(equipment: { id: [1, 2, 3] })
The problem is that I want to require all of those records, rather than requiring just one of them.
Is there a way to build a query that requires all of the values in the array (the [1, 2, 3] from the above example).
In other words, I'd like to query for all cars that have all three equipment (ids of 1, 2 and 3).
Assuming you have an id_ary like [1,2,3], how about something like:
id_ary.each_with_object(Car.includes(:equipment)) do |id, scope|
scope.where(equipment: {id: id})
end
Looping like that should and your where conditions, I believe.
I have an ActiveRecord object that has four String columns. I'd like to make a validation that verifies that a certain value is unique across all four columns. For example, assuming the four columns in question are named a, b, c, and d:
FooObject.new( a: 'bar' ).save!
should succeed, but
FooObject.new( b: 'bar' ).save!
should fail because there is already a FooObject whose value of either a, b, c, or d matches the value entered for b. Is there a neat, clean way to accomplish this validation on the object? Thank you!
arr = ["a", "b"]
arr.uniq{|x| x}.size //2
arr << "b"
arr.uniq{|x| x}.size // 2
2 == 2
hence this element already exists in the column
arr represents a temp copy of one row of FoObject
You can try a custom method:
validate :uniqueness_across_columns
def uniqueness_across_columns
cols = [:a, :b, :c, :d]
conditions = cols.flat_map{|x| cols.map{|i| arel_table[x].eq(self.try(i)) if self.try(i).present? }}
!self.class.exists? conditions.compact.reduce(:or)
end
What I wrong with me or this query?
I have a Shop model with an opening days column, which is an array of integers (something you can do with Postgres):
days= [1,1,1,1,0,0,0]
When I query:
shops = Shop.where('days[0] = 1')
I get an empty ActiveRecord Relation.
=> #<ActiveRecord::Relation []>
When I take a shop with this kind of array…
shop = Shop.first
=> #<Shop id: 215, days: [1, 1, 1, 1, 0, 0, 0],…
If I do
shop.days[0]
I get
=> 1
I really don't get it.
By default PostgreSQL uses a one-based numbering convention for arrays, that is, an array of n elements starts with array[1] and ends with array[n].
— Source
It's just your example. Your index is out of bounds, so it doesn't match any records, days[0] is NULL. Everywhere. Fire up rails db and figure:
SELECT * FROM shops WHERE days[0] IS NULL;
But what's with that "by default"? Is it possible to define array bounds on schema level so this never becomes an issue?
Well... it's Rails' fault, I'm afraid. If it's even considered an "issue" at all. In order for an array to be zero-indexed it should be saved as such in SQL. I tried that in SQL, it works:
INSERT INTO shops
(days, created_at, updated_at)
values('[0:2]={1, 1, 0}', current_timestamp, current_timestamp);
Unfortunately, Rails loses bounds for some reason:
Shop.create(days: '[0:3]={6, 7, 8, 9}')
> INSERT ... [["days", "{6,7,8,9}"], ...]
I had array of users, and array of they id's. I'm need create hash with {name => id}, but with order of id's array. As example, when i wrote:
keys = [5, 3, 2, 4, 1]
users = User.all.where(id: keys).pluck(:name, :id).to_h
It's return me {"User_1"=>2, "User_2"=>3, "User_3"=>4, "User_4"=>5, "User_0"=>1}
But i'm need to get such thing:
{"User_4"=>5, "User_2"=>3, "User_1"=>2, "User_3"=>4, "User_0"=>1}
Is there opportunity to had such hash on where operation?
The array of users that you get from your database is ordered by the updated_at column. Try this:
users = User.where(id: keys).order(id: :desc).pluck(:name, :id).to_h