Dynamic has_many queries using Ruby Mongoid and a array of hashes ex: user.send(:projects, "where(id: 1)")

StackOverflow https://stackoverflow.com/questions/22681571

  •  22-06-2023
  •  | 
  •  

Question

Hello I am trying my hand at some meta programming and am stuck. I would like to get has many associations via an array of hashes with names and maybe id's

# what I would like to get is 
user.projects.find(project.id).comments
# and or 
user.projects.find(project.id).comments.find(comment.id)
# using the array of hashes called a_h -> array_of_hashes
# I am stuck and am looking for some guidance.


# gem install mongoid

require 'mongoid'

begin
  Mongoid.load!("mongoid.yml", :development)
rescue
  Mongoid.load!("config/mongoid.yml", :development)
end

class User
  include Mongoid::Document
  include Mongoid::Timestamps
  field :name, type: String
  has_many :projects
end

class Project
  include Mongoid::Document
  include Mongoid::Timestamps
  field :name, type: String
  belongs_to :user
  has_many :comments
end

class Comment
  include Mongoid::Document
  include Mongoid::Timestamps
  field :name, type: String
  belongs_to :project
end

user = User.create( name: :user )
project = user.projects.create( name: :project )
comment = project.comments.create( name: :comment )
comment = project.comments.create( name: :comment )
comment = project.comments.create( name: :comment )
comment = project.comments.create( name: :comment )

a_h = [
  { name: 'users', id: user.id, position: 0 },
  { name: 'projects', id: project.id, position: 1 },
  { name: 'comments', id: nil, position: 2 },
]
# or comment with id
a_h = [
  { name: 'users', id: user.id, position: 0 },
  { name: 'projects', id: project.id, position: 1 },
  { name: 'comments', id: comment.id, position: 2 },
]

# this works but would like to be able to itterate over projects a_h[1] and comments a_h[2]
user.send( a_h[1][ :name ].to_sym, "find( '#{a_h[1][ :id ]}' )" )

scope = User.scoped( {} )
scope = scope.scoped.where( id: user.id) # .last but doesn't work with projects
scope = scope.projects.where( id: project.id)

# what I would like to get is 
user.projects.find(project.id).comments
# and or 
user.projects.find(project.id).comments.find(comment.id)

user.send( a_h[1..-1].map { |h| 
  [ h[ :name ], "find( '#{ h[ :id ] }' )" ] if h[ :id ].present?
  h[ :name ] if h[ :id ].blank?
} )

a_h[1..-1].map { |h| [ h[ :name ], "find( '#{ h[ :id ] }' )" ] }.flatten 

a_h[1..-1].map { |h| h[ :name ], "find( '#{ h[ :id ] }' )" } # doesn't work without array    
Was it helpful?

Solution

res = user
a_h[1..-1].each do |h| 
  res = res.send(h[:name]).send('find', h[:id]) if h[:id]
end
puts res
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top