If I have a model, ie. User, and each user has_many :animals, how do I get a retrieve the list of all of a particular set of User's animals?
I'd like to do something like this:
a = User.where(:last_name => 'Statham').animals
and have a be a list of the Animal objects. I assume I'm missing something trivial and simple.
Try this:
Animal.where(user_id: User.where(last_name: "Statham"))
Yep, simple is right. You're getting a lot of users there, so you need to iterate through them.
stathams = User.where(:last_name => 'Statham')
stathams.each { |statham| statham.animals }
And if you want to avoid duplicates:
animals = []
stathams = User.where(:last_name => 'Statham')
stathams.each { |statham| animals << statham.animals }
animals.uniq!
Related
I have a Convo table and a GroupMeeting table that both are associated with a Msg table.
I want to find all the instances where the current_user has convos or group_meetings with msgs, combine the two, and then show both together to the user in order of the last msg.created_at
Here I have defined both:
#convos = Convo.includes(:msgs).where("sender_id = ? OR recipient_id = ?", current_user, current_user).where.not(:msgs => { :id => nil }).merge(Msg.order(created_at: :desc))
#group_meetings = current_user.group_meetings.includes(:msgs).where.not(:msgs => { :id => nil }).merge(Msg.order(created_at: :desc))
And then combined them together:
#convos = #convos + #group_meetings
What I can't figure out is how to now sort them by msg.created_at
I have tried the following:
#convos = (#convos + #group_meetings).sort_by(&:"#{msg.created_at}")
#convos.order('msg.created_at DESC')
These all seem to be server-side sorting though. How can I sort these based off the join table, after the array has been created?
Please let me know if I need to supply any other details. Thank you!!
You can try the following:
(#convos + #group_meetings).sort_by { |item| item.msgs.minimum(:created_at) }
This query return an Array on users variable:
users = #users.flat_map {|b| b.followees_by_type('aged') }
I need apply this filter to users:
olds = users.any_of({ :image_filename.ne => nil }, { :yt_video_id.ne => nil}).all_of(:active.ne => false)
But I can not apply because is an Array.
Is possible change to mongoid criteria this array?
Any other solution?
Note important! I can not modify output class type b.followees_by_type('aged')
As per my comment, you should use #users which is a Mongoid::Criteria instead of users which is just an Array.
Is it possible to parse an array of objects to select them by attribute? I have a situation where I need to display all objects of a model grouped by an attribute on the index page. What I had been doing in my controller is this...
#xx_controller.rb
#group1 = City.where(:population => 'big')
#group2 = City.where(:population => 'medium')
#group3 = City.where(:population => 'small')
But I'd prefer to do something like this in the controller...
#cities = City.all
And in my view something along the lines of a query, rather than prepackaged instance variables -
#cities.where....
Any thoughts?
If you don't mind loading everything at once from the database, you can do:
#cities = City.all.group_by(&:population)
Which returns a hash whose keys are the possible values for the population attribute.
Then, on your view, you can access the cities on each 'group' by doing #cities['small'], #cities['medium'] and so on.
Do you mean something like this?
#cities = City.all
small_cities = #cities.select { |city| city.population == 'small' }
medium_cities = #cities.select { |city| city.population == 'medium' }
big_cities = #cities.select { | city| city.population == 'big' }
I am using ruby-aaws to return Amazon Products and I want to enter them into my DB. I have created a model Amazonproduct and I have created a method get_amazon_data to return an array with all the product information. When i define the specific element in the array ( e.g. to_a[0] ) and then use ruby-aaws item_attributes method, it returns the name I am searching for and saves it to my DB. I am trying to iterate through the array and still have the item_attributes method work. When i don't define the element, i get this error: undefined method `item_attributes' for #Array:0x7f012cae2d68
Here is the code in my controller.
def create
#arr = Amazonproduct.get_amazon_data( :r ).to_a
#arr.each { |name|
#amazonproduct = Amazonproduct.new(params[:amazonproducts])
#amazonproduct.name = #arr.item_attributes.title.to_s
}
EDIT: Code in my model to see if that helps:
class Amazonproduct < ActiveRecord::Base
def self.get_amazon_data(r)
resp = Amazon::AWS.item_search('GourmetFood', { 'Keywords' => 'Coffee Maker' })
items = resp.item_search_response.items.item
end
end
Thanks for any help/advice.
I'm not familiar with the Amazon API, but I do observe that #arr is an array. Arrays do not usually have methods like item_attributes, so you probably lost track of which object was which somewhere in the coding process. It happens ;)
Try moving that .item_attributes call onto the object that supports that method. Maybe amazonproduct.get_amazon_data(:r), before its being turned into an array with to_a, has that method?
It's not quite clear to me what your classes are doing but to use #each, you can do something like
hash = {}
[['name', 'Macbook'], ['price', 1000]].each do |sub_array|
hash[sub_array[0]] = sub_array[1]
end
which gives you a hash like
{ 'name' => 'Macbook', 'price' => 1000 }
This hash may be easier to work with
#product = Product.new
#product.name = hash[:name]
....
EDIT
Try
def create
#arr = Amazonproduct.get_amazon_data( :r ).to_a
#arr.each do |aws_object|
#amazonproduct = Amazonproduct.new(params[:amazonproducts])
#amazonproduct.name = aws_object.item_attributes.title.to_s
end
end
What's the simplest way to get an array with three objects (Card), one of which I already have? The other two should be randomly selected from the database.
My current approach looks like this:
[
#deck.cards[rand(#deck.cards.size)],
#deck.cards[rand(#deck.cards.size)],
#mycard
].sort_by {rand}
The problem I have right now is that sometimes #mycard shows up twice in the array. How can this be avoided?
something like this might work:
class Card < ActiveRecord::Base
belongs_to :deck
named_scope :random, lambda {
{ :offset => Kernel.rand(Card.count) }
}
named_scope :not_in, lambda { |a|
{ :conditions => [ 'id NOT IN (?)', a ] }
}
end
my_cards = []
#mycard = Card.last
my_cards << #mycard
2.times {
my_cards << #deck.cards.not_in(my_cards.collect(&:id)).random
}
Get a card from the deck. Check it's not the samy as #mycard.
Get another card from the deck. Check it's not the same as #mycard or the previous card.
Pretty straightforward, I'd have thought.
You have to remove each card from the deck as you draw from it, unless you are going to reshuffle after each draw, in which case I would just draw again until you get a unique one you haven't already drawn.