lundi 23 novembre 2015

Dynamical query: get some (not all) of the has_many associations- with only selected values


Hello, I would like to make a query on users that would preload its addresses but with some conditions.

Simple? users = User.include(:addresses) will work. but I have 2 more conditions to add.

class User < ActiveRecord::Base
  has_many :addresses
end

class Address < ActiveRecord::Base
  belongs_to :user

  attr_accessible :box_number, :name, :content1, :content2, :content3
end

        #example output: [10, 7, 39, 14, 10, 10, 20, 20, 37, 4, 37]
        def get_random_integer_array
          (0..10).collect{ rand(50) } #example ouput: 
        end

    #example ouput: [:name, :content1]
        def get_random_attributes_array
          random_number = rand(3)
          case random_number
            when 0
              [:name]
            when 1
              [:name, :content1]
            when 2
              [:content2]
            else
              [:name, :content1, :content2, :content3]
          end
        end

1) I don't want all addreses. I would like only the addresses which their box_number (integer) will match one of the given dynamic integer array.

random_array =  get_random_integer_array
=> [24, 28, 41, 47, 30, 5, 3, 44, 14, 25, 41]

So like: Address.where(id: random_array) but to 'glue' it to the User's query

2) After that's done. I don't want to addresses to contain their entire attributes, (:name, :content1, :content2, :content3), only a selected few. Again, like Address.select([:name, :content1]) - just 'glue' it to the User query

I have users, each of them has_many addresses. I would like to display all the users in a table, each row is a single user, additionally, that row will contain the user's (selected) addresses

So for example: if random_box_number_array = get_random_integer_array rolled: [3,6,9] and random_attributes = get_random_attributes_array rolled [:name, :content1]

I would like query to match that: meaning users = User.

To summarize: I would like a query on users, which will:

  • load all users, while
  • preloading only the selected addresses for each user, but
  • for the addresses to only contain( so they wouldn't load) the desired attributes.

And to further explain:

users = User.include(:addresses)
first_user = users.first

first_user_addresses = first_user.addresses
first_user_addresses.find_by_box_number (10)
#=> will fetch it 
first_user_addresses.first.content2
#=> will fetch content2



#but
box_numbers = [1,3,5] #not 10
attributes = [:name, :content1] #not content2
users = User.some_magic_query(box_numbers)
first_user = users.first

first_user_addresses = first_user.addresses
first_user_addresses.find_by_box_number (10)
#=> will not find it

#and
first_user_addresses.first.content2
#=> will not find it

Aucun commentaire:

Enregistrer un commentaire