Export postgres table based on rails relation - ruby-on-rails

I have a user table that I can easily export with postgres by doing
\copy users to 'tmp/users2015.csv' csv header
My users has_many questions, and I'm wondering if there's a way I can export just the users who have asked a question. The problem is here's no column in my users table that represents the number of questions a user has asked, so I don't think I can do this. Is there any possible way or a different approach? I really care about just knowing how many users have asked questions, so I could also export my questions table, and possibly filter out questions that have been asked by the same user?

You can execute the same select query that the has_many relationship uses and use that to write to a file.
Copy (Select * From users where <some condition>) To '/tmp/test.csv' With CSV
See Save PL/pgSQL output from PostgreSQL to a CSV file for more info.

Your should export in additional to the user table a table which has a belongs_to field, for example of question table, to 'tmp/question2015.csv' CSV.

Related

How to design database tables for different types of Users?

I'm on a project with Rails, Postgresql and Active Record, where I have Users, that can be either Influencers, or Creators.
The Users have common columns such as email, password, first_name and last_name, but :
influencers will have followers, eg_rate, account columns
creators will have SIRET_number and specialty columns
How can I design my database so Influencers and Creators are kind of "child" of the Users table ? I mean, is it possible to have a db where I can access a User' followers or a User's specialty with one query, or I'll always have to do multiple queries to achieve this ? I've tried to create three tables for each, with a foreign key user_id in Influencers table and Creators table. I also tried to add a user_type column to my User table where I pass the values of either "influencer" or "creator", but I'm kind of lost on how to link every tables...
Thank you everyone.
Your approach is right.
You can create a table users with the common columns and add a foreign key to influencers and creators tables.
Then when you need to retrieve the data, you can use ActiveRecord relations to easily fetch data and use ActiveRecord's includes method for relations.
For example:
class Creator < ActiveRecord::Base
# The relation must be set
has_one :user
end
# To fetch data anywhere else:
Creator.find_by(SIRET_number: 1234).includes(:user)
If you need to retrieve a creator or influencer by an attribute from related users table, you can use joins:
Creator.joins(:users).where(users: {email: "foo#bar.com"})
Make sure you have the relations set in both User and Creator models.
Check out this topic for more info.
By using includes or joins instead of using creator.user you'll avoiding the unnecessary additional query. The downside is the syntax is now longer, you can maybe create your own getters to easily retrieve data instead of writing "includes" everytime.
Also assuming you're not aware of this method, I suggest you to read about the common N+1 problem with Rails & ActiveRecord. The same methods can solve a lot of problems for you.

Database record containing multiple entries in one column

I am working on a web app written in rails. It is currently running on heroku with a postgres database.
I am supposed to add a feature where users may enter up to three codes for each one of the user's students. The codes themselves are irrelevant, they are simply strings that will be entered into the database.
This brings me to my dilemma. I am unsure of how to best store the codes in terms of their relationship to the student table. My original thought was to use the rails method serialize to store up to three codes in an array, but I have read that more often than not, storing data in an array in a database is not what you want to do.
Should I create a new table "codes" and set up a has_many relationship with the "students" table? Or is there a more preferable away to set up this relationship?
Given your situation, this sounds like the most reasonable approach to have a Code model and then setup has_many association with Student model.
student has_many codes and
code belongs_to student.

Postgres HStore vs HABTM

I am building an app that has and model that can be tagged with entries from another model, similar to the tagging function of Stackoverflow.
For example:
class Question < ActiveRecord::Base
has_and_belongs_to_many :tags
end
class Tag < ActiveRecord::Base
has_and_belongs_to_many :questions
end
I am debating between just setting up a has_and_belongs_to_many relationship with a join table, or adding the tags to a hash using Postgres' hstore feature.
Looking for anyone that has had a similar experience that can speak to performance differences, obstacles, or anything else that should persuade me one way or another.
EDIT:
I think I should also mention that this will be a API that will be using an AngularJS frontend.
You are describing the topic of a great debate:) Normalization vs denormalization. Using many to many allows you to do nice queries such as "how many people use a certain tag" in a very simple way. HStore is very nice as well but you end up with thousands of the same tags everywhere. I use both approaches in different projects but the real problem comes when you decide one day to move your database. With Hstore you will be stuck to postgresql or have to rewrite your code. If super high speed is important as well as querying different ways and you often want to load a user record in one fellow swoop as fast as possible and show all used tags I normally do both: create a many to many relationship as tags are normally also connected to more objects like user has many tags from tags table and tags are connected to let's say brands which are connected to products and so on.
Then I create an additional field with hstore or json objects on the user table which adds every tag or removes it when the many to many relationship is destroyed.
To give you an example: in on of my projects I have companies (almost 10 million) who are interested in certain keywords and their ranking on google. This table has millions of rows but connected only to 2 million keywords which are connected to search results. This way I can quickly query which result is searched for by how many people and who they are.
If a customer opens their key word search page I load their keywords from a text column with json which is faster than going through the table.

Loading all the data but not from all the tables

I watched this rails cast http://railscasts.com/episodes/22-eager-loading but still I have some confusions about what is the best way of writing an efficient GET REST service for a scenario like this:
Let's say we have an Organization table and there are like twenty other tables that there is a belongs_to and has_many relations between them. (so all those tables have a organization_id field).
Now I want to write a GET and INDEX request in form of a Rails REST service that based on the organization id being passed to the request in URL, it can go and read those tables and fill the JSON BUT NOT for ALL of those table, only for a few of them, for example let's say for a Patients, Orders and Visits table, not all of those twenty tables.
So still I have trouble with getting my head around how to write such a
.find( :all )
sort of query ?
Can someone show some example so I can understand how to do this sort of queries?
You can include all of those tables in one SQL query:
#organization = Organization.includes(:patients, :orders, :visits).find(1)
Now when you do something like:
#organization.patients
It will load the patients in-memory, since it already fetched them in the original query. Without includes, #organization.patients would trigger another database query. This is why it's called "eager loading", because you are loading the patients of the organization before you actually reference them (eagerly), because you know you will need that data later.
You can use includes anytime, whether using all or not. Personally I find it to be more explicit and clear when I chain the includes method onto the model, instead of including it as some sort of hash option (as in the Railscast episode).

Dynamically creating new Active Record models and database tables

I am not sure exactly what I should name this question. I just started server-side programming and I need some help.
All the tutorials I have read so far on RoR deal with creating a pre-defined table and with pre-defined fields (id, name, email, etc etc). They use ActiveRecord as base class and saving to db is handled automatically by superclass.
What I am trying to program is something that allows user-defined table with fields. So think of this way. The web UI will have an empty table, the user will name the table, and add columns (field), and after that, add rows, and then later save it. How would I implement this? I am not asking for details, just an overview of it. As I said, all the tutorials I have read so far deal with pre-defined tables with fields where the ActiveRecord subclass is predefined.
So in a nutshell, I am asking, how to create tables in db on runtime, and add fields to the tables.
Hope I was clear, if not, please let me know and i will try to elaborate a bit more.
Thanks.
Unless you're building a DB administration tool (and even maybe then), allowing the user direct access to the database layer in the way you're suggesting is probably a bad idea. Apart from issues of stability and security, it'll get really slow if your users are creating lots of tables.
For instance, if you wanted to search for a certain value across 100 of your users' tables, you'd have to run 100 separate queries. The site would get exponentially slower the more user tables that were created.
A saner way to do it might be to have a Table model like this
class Table < ActiveRecord::Base
has_many :fields
has_many :rows
end
Every table would have fields attached to it, and rows to store the corresponding data (which would be encoded somehow).
However, as #Aditya rightly points out, this is not really beginner stuff!
I agree with previous answers generally speaking. It's not clear from your question why you want to create a table at runtime. It's not really obvious what the advantage of doing this would be. If you are just trying to store data that seems to fit into a table with rows and columns, why not just store it as an array in a field of your user table. If your user is allowed to create many tables, then you could have something like
class User < ActiveRecord::Base
has_many :tables
end
and then each table might have a field to store a serialized array. Or you could go with Alex's suggestion - the best choice really depends on what you are going to do with the data, how often it changes, whether you need to search it and so on ...
You can create a database as shown in tutorials which stores name of tables and their columns name those your user want. Then you can have worker (which can be build using Redis and Resque, here is simple Tut on Resque and Redis) and have those worker run migration (write migration with variables and use params to replace them) for you for new table in DB as soon as new entry is made in database. Tell me if you have questions on this.

Resources