Get all items of some other items - ruby-on-rails

I will give an example:
Books.find(THIS_FIND_MAY_GET_MORE_THAN_ONE_BOOK).pages.all
I am expecting a set of pages... Every page returned should be contained in at least one book. Otherwise it shouldn't be in the set. How can I get such a set?
My intuitive idea was looping over the books and then add every time, but i guess there may be a faster way (databasewise), as I am not interested in the books. I don't want to introduce further database links as I think they may lead to a inconsistent database.
Any suggestions? Thanks!

To get all of the pages for each book...
books=Books.find(:all)
...will give you an array of books. Then you can loop over every book to get its pages...
books.each do |book|
puts book.pages
end
This assumes you have setup a relation between books and pages where each book has many pages and each page belongs to a book.

I'm not that sure on what you really want to do, but since you want pages instead of books, why not use Page.find_by_book_id or by whatever else you want and pass an array with the book ids for instance.
If this is not what you really want, could you please provide some more information on what you want to achieve ? Maybe a scope can work for you, maybe you can write some more info so that i can help you any further.

I guess this is what you want:
pages = Page.where("book_id is not NULL")

Related

Display Sorted Column on Static Page in Rails

I am creating a website that allows users to evaluate their coworkers. My boss would like the averages to be displayed from best to worst on a static page that she can print and hang up in our store, so the employees can see their results compared to other employees. I have been searching for awhile now on how to easily sort a column. I found a Railscast on sorting columns, but it seems a lot more detailed than I truly need. I found the order API, but I don't think I'm implementing it the way I need to. I am hoping that maybe there is a one-liner that can help me solve this problem, such as:
#user = User.all.order(average: :asc)
Where I can load a static page that prints the user's name and their score. Thank you in advance!
Have you tried that code of yours? It should do exactly what you're asking except from lowest score to highest score.
You could simplify it a little and sort from highest to lowest by doing:
#users = User.order(average: :desc)
Like MarsAtomic said, this assumes that you actually have a column in your users table called average. If not we need more information on how your database is set up.

How to remove some items from a relation?

I am loading data from two models, and once the data are loaded in the variables, then I need to remove those items from the first relation, that are not in the second one.
A sample:
users = User.all
articles = Articles.order('created_at DESC').limit(100)
I have these two variables filled with relational data. Now I would need to remove from articles all items, where user_id value is not included in the users object. So in the articles would stay only items with user_id, that is in the variable users.
I tried it with a loop, but it was very slow. How do I do it effectively?
EDIT:
I know there's a way to avoid doing this by building a better query, but in my case, I cannot do that (although I agree that in the example above it's possible to do that). That thing is that I have in 2 variables loaded data from database and I would need to process them with Ruby. Is there a command for doing that?
Thank you
Assuming you have a belongs_to relation on the Article model:
articles.where.not(users: users)
This would give you at most 100, but probably less. If you want to return 100 with the condition (I haven't tested, but the idea is the same, put the conditions for users in the where statement):
Articles.includes(:users).where.not(users: true).order('created_at DESC').limit(100)
The best way to do this would probably be with a SQL join. Would this work?
Articles.joins(:user).order('created_at DESC').limit(100)

rails and an up/down rating system

sorry if it's duplicate, I've been looking for something similar before posting, but no success.
So basically I need an up/down rating system ( it's very similar to the one here on stackoverflow ).
I have 6 rateable models, so polymorphic association seem to be the best option.
But since this table will probably hold a solid number of records, won't it take too much time to get the item rating ( upvotes_count - downvotes_count )?
I actually though about adding a new row to each and every rateable model, something like current_rating_value. So that this value will be changed every time the rating object will be created/destroyed.
Could you please advice, what might be a better option in this case? Extra UPDATE call to change the current_rating_value or an extra SELECT(SUM...) call to calculate it?
Depending on how much traffic you get loading these models it could tax resources more then desired. I've ended up using acts_as_votable gem in my projects. Its very easy to make a model votable and it also caches the data which is also awesome.
for the long-term performance, you should add something like current_rating_value into every ratable model. Everytime there is new rate, just update this field.
Otherwise, it will be very harmful to performance when you have to calculate the rating everytime.

Returning Search Results in Rails

I am having a problem implementing a special kind of search for my Rails application. I am working on an achievement system where you can search for a set of users in a search form (e.g., the query being "Ross, Adam, Jake") and it returns all of the common achievements that the users have unlocked (e.g., if users Ross, Adam, and Jake all had an achievement named "You are winner!"). I have three tables, one for achievements, one for users, and a join table. We have tested the associations and such, so we know that works.
My first idea was to put the search terms in an array and get the search results for each item in the array and place them into respective "search result arrays". Then, I was thinking to go through each item in search result array 1 to see if it appears in both of the other result arrays. The objects that appear in all three of the search result arrays would be returned and displayed on a page.
Is there an easy way to implement this without writing a bunch of my own code? Are there some functions I should know about? Any help will be appreciated!
Well, both Ransack and it's predecessor (MetaSearch) are useful gems for creating complex search forms.
In general I think you want to do something like select distinct achievement ids for user ids in an array. Off the top of my head I'm not quite sure how you should write it... others may know.
Look at the documentation on MetaSearch (more established) and see if you see a pattern that fits, if not check Ransack (more advanced).
You can use some autocomplete plugin for user names and convert the names to ids on the fly, that way you won't have to deal with converting user names to ids in backend later.
For common achievements, if a user can have a achievement only once, aggregating the results in join table and counting the results with achievement ids would be the way to go.
You can provide more details for a more detailed answer. :)
You can use Sunspot which is allows easy solr integration with Ruby and Rails

Rails: Removing unnecessary database queries

Say I have a post and category model, with each post belonging to a category. On pretty much every page, I'm getting the list of categories:
#categories = Category.all
This produces an array of Category objects. Now, say that each category has id and name attributes. When viewing a post, I want to display the category name.
I was originally getting the category name by doing something like this:
#post = Post.find(params[:id], :include => :category)
However, I realize that I already have the #categories array. It seems unnecessary to :include when I already have a list of categories. So, instead, I'm now performing a find on the array:
category = #categories.find { |category| #post.category_id == category.id }.name
This works and reduces the number of queries. My question is if this is the best way to tackle reducing the number of queries (without caching)?
That's perfectly sensible.
The only risk (and it's a miniscule one) is that you are possibly subject to a race condition. For example, someone could change the post's category after you fetched the categories list, or they could update the list of categories, and what you're showing would no longer be correct. Subsequently, if they, say, clicked on a category name to get a list of all posts with that category, they'd probably get an error unless you were handling that sort of thing.
IMO, that's an awfully small price to pay, though.
The only issue here would be when you decide you don't need the categories list anymore and try removing it.
Otherwise you got a good solution.
And what if you have a large number of categories? Are you still going to be fetching them all? Doing an :include is much better as SQL will always win over Ruby.

Resources