Why Index is Needed for Rails Model Association - ruby-on-rails

I'm a bit confused on the topic of index columns in model associations.
(From the The Rails 4 Way) We have User, Timesheet, and Expense Report models.
The User model:
has_many: timesheets
has_many: expense_reports
(along with the corresponding belongs_to in the other models)
The Rails 4 Way book says to add_index into the timesheets and expense_reports model as so:
add_index :timesheets, :user_id
add_index :expense_reports, :user_id
I don't understand the reasoning for adding an index after every foreign key column. The timesheet and expense_report tables already have a primary_key column so why isn't that used for "performance boos?" Adding two additional indices seems redundant to me? Can someone explain the benefit?

I can see where your frustration comes from, just follow along and I am sure you'll get it pretty fast...
Problem:
When you create a column in a database, it is vital to consider whether you will need to find and retrieve records from that column. So, lets say we have a User table and every user has an email, that in many applications is used for authentication and authorization of users. When we allow users to log in to our application, we will need to find the user record corresponding to the submitted email address. Unfortunately, the only way to find a user by email address is to scan through each user row in the database and compare its email attribute to the given email - which, therefore, implies we might have to examine every row(since the user can be the last person inside the database). This would take a lot of time as you can imagine. Simply, this is not good.
Solution:
Putting an index on the email column would fix the problem. Think of it as an appendix at the end of the book. In a book, to find all the occurrences of a given string, say “foobar”, you would have to scan each page for “foobar” - the paper version of a full-table scan. With a book index, on the other hand, you can just look up “foobar” in the index to see all the pages containing “foobar”. A database index works essentially the same way.
I hope this helps you out.

Related

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.

how to avoid empty fields in a database

Frustrated with the Active Record Reputation gem, which I found very buggy, I'm trying to make my own reputation system for a Rails app. It's very primitive. I created a Contribution resource with a user_id and a value field, with an association between User.rb and Contribution.rb. Every time a user contributes to the app in some way, they get some points. If they ask a question, these lines get included in the create action of the Questions controller.
#contribution = current_user.contributions.build({:value => 3})
#contribution.save
If a user edits some Tags on the site, I do the same thing to reward superusers for their administrative work
#contribution = current_user.contributions.build({:value => 2})
#contribution.save
It then becomes very easy to calculate a user's total reputation.
One problem with this is that, in an imaginary world where users care about this app and their reputation, it would be very easy to game the system. For example, a user could just keep updating the categories or tags, and every time they do so they get 2 more points. Therefore, I wanted to somehow record what type of action the user did.
Right now, all of the work users can earn points for is somehow associated with a Question.rb, however, they get points for updating Tags, updating Categories, upvoting other people's answers etc, therefore merely storing the question_id in the contributions model wouldn't be sufficient.
Based on what I told you, can you give me some idea how I might build out the Contributions resource in order to accomplish what I want?
For example, I thought of one way of doing it that would have left a lot of null fields in my database, so I assumed it wasn't a good way. I could add a question_id and several boolean fields such as 'answering_question' 'updating_category' 'updating_tags' and each time an action is performed, record with a 'true' whether, for example, 'updating_category' is being performed. However, as mentioned, if I start rewarding lots of different types of contributions, there's going to be a lot of columns in each row that aren't being used.
I'm not sure if that's a 'real problem' (i've read about it but not sure how necessary it is to avoid), or if there's a better way of recording what type of activity each user is engaging in to earn points.
some of the current associations
User has_many :answers
Question.rb has_many :categories
Question.rb has_many :tags
for my rails application I am using thumps_up gem which is better than active_record_reputations_system ,Its more simple.
https://github.com/bouchard/thumbs_up

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.

Rails: Is a single table a good design choice for this problem?

I just recently inherited a Rails application and am debating an architectural decision moving forward. Here's a bit of background... Feedback appreciated.
There are, currently, 16 different ad types, all with a set of the same attributes, several with one or two additional attributes, and a couple with three or four.
Currently each ad type has a separate model and table with the respective columns, and a separate controller and views in a CMS too used for basic CRUD. The CMS takes advantage of inherited_resources, so that limits some of the duplication.
I wrote out the attribute set -- there are 20 or so that cover all ad types. Certain ad types have associations -- several has_many associations where the foreign key is stored on the associated table and a few belongs_to.
The ads have no real behavior. Specific ad types are simply displayed on various pages, so as long as I can determine if there is an ad of a specific type, we're golden.
I am debating moving to a single model, table, and controller, but want to get as much input as possible from the stackoverflow community on whether or not this is 1) a good fit for the problem 2) any performance concerns 3) any potential programming bottlenecks I haven't though of. Here is my thinking so far...
Assuming a route /:location/:ad_type/new (e.g. /homepage/ad_type_1/new):
The ad_controller would create #ad with ad_type set to params[:location] + params[:ad_type] and render the new view which would contain a series of conditionals for displaying the appropriate partials for the given ad_type. Submit would fire the create action creating the ad with the expected attributes defined for the ad type, one of which in this case would be ad_type = homepage_ad_type_1.
I've not thought as much about retrieving the data, but assuming the ad_type column is set correctly, I should be able to create an "of_type" scope that pulls records based on the ad_type column. Not sure if I'm missing something there.
Validations will vary based on the ad_type value.
I'm not entirely certain how many ads will exist at any given time, but I feel this could be addressed at a later time. Either by moving off some of the stale rows to an ad_archives table or similar.
Your thoughts are appreciated. Thanks.
I would probably use a single table model for this, but if it makes sense to use multiple controllers/views, you don't have to restrict yourself to a single controller, and you can still query ads based on their type without using conditionals. Example:
create_table :people do |t|
t.string first_name
t.string last_name
# some other properties...
t.string type
end
class Student < Person
end
class Teacher < Person
end
Person.all # shows all students and teachers
Teacher.all # shows all teachers
So it would be easy to make a Teachers controller and a Students controller, as well as a People controller.

Resources