Skip to content

Commit

Permalink
Fixed select/exclude graph attributes on many to many relation
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Naiman committed Apr 28, 2020
1 parent f0ee9ed commit 97aa1b2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
21 changes: 13 additions & 8 deletions lib/rasti/db/relations/many_to_many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,27 @@ def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=
if target_collection_class.data_source_name == relation_data_source_name
target_data_source = environment.data_source_of target_collection_class

join_rows = target_data_source.db.from(qualified_target_collection_name(environment))
.join(qualified_relation_collection_name(environment), target_foreign_key => target_collection_class.primary_key)
.where(Sequel[relation_collection_name][source_foreign_key] => pks)
.select_all(target_collection_class.collection_name)
.select_append(Sequel[relation_collection_name][source_foreign_key].as(:source_foreign_key))
.all
dataset = target_data_source.db.from(qualified_target_collection_name(environment))
.join(qualified_relation_collection_name(environment), target_foreign_key => target_collection_class.primary_key)
.where(Sequel[relation_collection_name][source_foreign_key] => pks)
.select_all(target_collection_class.collection_name)

selected_attributes ||= target_collection_class.collection_attributes - excluded_attributes if excluded_attributes
dataset = dataset.select(*selected_attributes.map { |a| Sequel[target_collection_class.collection_name][a] }) if selected_attributes

join_rows = dataset.select_append(Sequel[relation_collection_name][source_foreign_key].as(:source_foreign_key)).all
else
relation_data_source = environment.data_source relation_data_source_name

relation_index = relation_data_source.db.from(relation_data_source.qualify(relation_collection_name))
.where(source_foreign_key => pks)
.select_hash_groups(target_foreign_key, source_foreign_key)

target_collection = target_collection_class.new environment
query = target_collection_class.new environment
query = query.exclude_attributes(*excluded_attributes) if excluded_attributes
query = query.select_attributes(*selected_attributes) if selected_attributes

join_rows = target_collection.where(target_collection_class.primary_key => relation_index.keys).raw.flat_map do |row|
join_rows = query.where(target_collection_class.primary_key => relation_index.keys).raw.flat_map do |row|
relation_index[row[target_collection_class.primary_key]].map do |source_primary_key|
row.merge(source_foreign_key: source_primary_key)
end
Expand Down
38 changes: 30 additions & 8 deletions spec/query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,51 @@
end

it 'Select graph attributes' do
person = Person.new db[:people].where(document_number: 'document_2').select(:first_name, :last_name, :user_id).first
language = Language.new custom_db[:languages].where(id: 1).select(:id).first

person = Person.new db[:people].where(document_number: 'document_2').select(:document_number, :user_id).first.merge(languages: [language])

user = User.new db[:users].where(id: 2).select(:id).first.merge(person: person)

post = Post.new db[:posts].where(id: 1).first.merge(user: user)
categories = db[:categories].where(id: [1,2]).select(:id).map { |c| Category.new c }

post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)

selected_attributes = {
user: [:id],
'user.person' => [:document_number, :user_id],
'user.person.languages' => [:id],
categories: [:id]
}

posts_query.where(id: 1)
.graph('user.person')
.select_graph_attributes(user: [:id], 'user.person' => [:first_name, :last_name, :user_id])
.graph(*selected_attributes.keys)
.select_graph_attributes(selected_attributes)
.all
.must_equal [post]
end

it 'Exclude graph attributes' do
person = Person.new db[:people].where(document_number: 'document_2').select(:document_number, :last_name, :user_id).first
language = Language.new custom_db[:languages].where(id: 1).select(:id).first

person = Person.new db[:people].where(document_number: 'document_2').select(:document_number, :user_id).first.merge(languages: [language])

user = User.new db[:users].where(id: 2).select(:id).first.merge(person: person)

post = Post.new db[:posts].where(id: 1).first.merge(user: user)
categories = db[:categories].where(id: [1,2]).select(:id).map { |c| Category.new c }

post = Post.new db[:posts].where(id: 1).first.merge(user: user, categories: categories)

excluded_attributes = {
user: [:name],
'user.person' => [:first_name, :last_name, :birth_date],
'user.person.languages' => [:name],
categories: [:name]
}

posts_query.where(id: 1)
.graph('user.person')
.exclude_graph_attributes(user: [:name], 'user.person' => [:first_name, :birth_date])
.graph(*excluded_attributes.keys)
.exclude_graph_attributes(excluded_attributes)
.all
.must_equal [post]
end
Expand Down

0 comments on commit 97aa1b2

Please sign in to comment.