Rails :HOw to order a table by associated model - ruby-on-rails

I think the problem is trivial. I have two models: User and Betting.
User
has_many :bettings
Betting
belongs_to :user
I just want to get the users ordered by who made more bettings.

Are you on Rails2 or Rails3?
On Rails3, you can use the Ruby sort method and something like:
User.includes(:bettings).sort{|x,y| x.bettings.size <=> y.bettings.size}
Of course, in this case the sorting occurs after the SQL request, which is not optimum if you have large tables… I'm trying to figure how to do it at the SQL level with no answer yet…

Related

In a belongs_to has_many relationship in Rails, how does the 'singlular' side access records from the 'many' side?

It was my understanding that all keys are stored on the 'many' side, ie: if a user has many posts, and posts belong to only one user, foreign keys associating which user "owns" which which post exist only in the post object.
Yet, in my users controller, I can still create a user show page which lists all posts by looping through 'user.posts'.
How is this possible?
Thanks in advance.
Edit: one caveat, I'm using MongoDB / Mongoid, not sure how this pans out with Active Record.
The model with belongs_to part holds the column for reference, user_id in your situation.
The model with has_many part queries the table, where belongs_to is, to get all references models.
Hope it helped you!

Filtering a Mongoid collection through relations

I'm using Mongoid to build a Rails 4 app.
The problem I'm having right now is how to filter some Mongoid objects through their own relations and have a Mongoid::Criteria at the end instead of an Array.
This is some example code:
class Editor
include Mongoid::Document
has_many :books
def likes
books.collect { |book| book.likes }
end
end
class Book
include Mongoid::Document
belongs_to :editor
end
What I would like to be able to do is something like:
Editor.last.likes.where(:created_at.gt => 10.days.ago)
but of course this doesn't work as Editor.last.likes returns an Array, not a Mongoid::Criteria
I know Mongoid has an aggregation framework but it's not entirely clear to me how to use it, nor if it's the best way to solve my problem.
Suggestions?
TIA,
ngw
The biggest problem you have here is that MongoDB does not do joins like a relational database does. All of the work you are getting for convenience when traversing object properties is being done client side while pulling in the 'related' documents over the wire in a query. But in sending a query, the two collections cannot be joined.
Your workaround solution is to work with the data you can get at in separate queries in order to target the results. One approach is here: rails mongoid criteria find by association
There should be other examples on Stack Overflow. You're not the first to ask.

Commenting "the rails way" - regarding table relationships and the rails way or tackling problems

I'm looking to implement a site wide comment/message feature into my apps entities. This will enable people to comment on the following modules
Newsletters
Reports
Tasks
and user to user (messaging)
My plan would be to make a foreign key called "entity_id" which doesn't relate to any single table. Instead, it's coupled with commentEntity_id which is a list of all the tables that can be commented on.
Example:
So a comment would have a CommentEntity which points to Reports and also an entity_id which, in this case, is the id of the Reports table.
The way I would build this is to make the following tables
Comment #along with user_id and a comment body:string, this will also have a commentEntity_id and a entity_id
CommentInvolvement # simply everyone involved (either by commenting on the entity, or in the case of user to user, **being** the entity)
CommentEntity # This is the join between the comment and the place
it's put.
This would be my solution in a PHP project, though I understand Rails requires a different way of thinking, so I would like to get the community's thoughts on this problem, and wheather this is the best way to tackle it?
Thanks
Yes, Rails supports this approach through Polymorphic associations
comment.rb
belongs_to :commentable, polymorphic: true
other models
has_many :comments, as: :commentable
Note: You have to add two columns in comments table commentable_id(Integer) and commentable_type(String)
you should also check out the great RailsCast regarding Polymorphic Associations
d

Ruby on Rails working with pre-existing database. Rails makes everything plural

What is the deal with this? I'm working with a pre-existing that I did not do myself. Everything in the database is labeled in singular form. user, security, spec, etc. I guess the right way would be users, securities, specs. At least that's what ruby on rails try's to lookup when I generate a scaffold .
How do I specifically state to use user instead of users in the sql. I don't see anywhere in my project where it is looking up the sql. I mean if my model is user you would think it would try to lookup user. Instead of users.
Thanks for any help.
You need set_table_name :name_of_the_table in your model (source).
So:
class User < ActiveRecord::Base
set_table_name :user
end
The reason they use plural for the table and singular for the model is because an instance of the model represents one user, whereas the table contains all the users. It's just to make it more readable and logical.
You can specifiy the table name:
How do I explicitly specify a Model's table-name mapping in Rails?

Rails Trouble creating model instance with one to many relationship

I think there are a lot of places where my design may be screwing this up. I have very limited experience with Rails though. This is happening in Rails 2.3.2 with Postgres 8.3.
We've got two tables in our DB. One called "survey" and one called "survey_timepoint". A survey can have multiple time points so in the survey_timepoint table there is a column called "survey_id" with an fk constraint on it.
I also think I should mention that the tables were not created with a rails migration although they do follow the rails naming conventions. I suspect AR isn't anticipating a constraint on that column and it doesn't know how to handle the situation.
In my rails models I have:
has_many :survey_timepoint
and
belongs_to :survey
If I do something like:
s = Survey.new
s.survey_timepoint.push SurveyTimepoint.new
s.save!
I get:
ActiveRecord::StatementInvalid: PGError: ERROR: insert or update on table "survey_timepoints" violates foreign key constraint "survey_timepoints_fk"
DETAIL: Key (survey_id)=(59) is not present in table "surveys"
I'm assuming that if I delete that fk constraint on survey_timepoint.survey_id it'll work ok. It seems like I shouldn't have too though. Am I going to be stuck creating and saving each of the objects separately and wrapping the whole process in a transaction? It seems rather un-railsy. Apologies for any necessary information that I may have omitted.
You might want to check the SQL commands being sent. It looks like it is adding the survey_timepoint record before the survey record. Note that you are already dealing with two database changes — the survey and the survey_timepoint — so you should be using a transaction.
You can fix the immediate problem by doing s.save! before adding the timepoint (and then calling it again). My knowledge of Rails functionality is not deep enough to know if there is a more "railsy" way of doing this then wrapping it in a transaction.
I just experimented and found that this works with MySQL:
s = Survey.new()
s.survey_timepoints << SurveyTimepoint.new # Note "survey_timepoints" (plural)
s.save!
I think it would work equally well with PostgreSQL.
It does two inserts, first the Survey, then the timepoint, and wraps them in a transaction.
You can also do it all on one line:
Survey.create!({:name=>'New Survey', :survey_timepoints => [SurveyTimepoint.new]})
Incidentally, for ActiveRecord to work right you have to make sure of your singulars and plurals. (If you want to break the expected forms, you'll need to tell AR you're doing that -- a whole other topic.)
Your tables should be:
surveys
-------
# ...
survey_timepoints
-----------------
survey_id
# ...
And in your models you'd have:
class Survey < ActiveRecord::Base
has_many :survey_timepoints
# etc...
end
class SurveyTimepoint < ActiveRecord::Base
belongs_to :survey
end

Resources