Create Rails Model Associations for has_many and owned by_to

Good. I am new to Rails, and I know that this was asked before, but I still don't understand how to approach the next general problem. I can make the association work, but something magical to do and run rails with bad habits is not what I want to do.

Say I'm building a blog. I have two resources: articles and users. Each user has many articles, and each article belongs to one user:

rails g scaffold User name:string email:string rails g scaffold Article user_id:integer title:string content:string 

User Model:

 class User < ActiveRecord::Base has_many :articles end 

Article Model:

 class Article < ActiveRecord::Base belongs_to :user end 

Now, in my article index, I can do something like:

 …table headers... <% @articles.each do |article| %> <tr> <td><%= article.user.name %></td> <td><%= article.title %></td> <td><%= article.desc %></td> <td><%= article.content %></td> <td><%= link_to 'Show', article %></td> <td><%= link_to 'Edit', edit_article_path(article) %></td> <td><%= link_to 'Destroy', article, confirm: 'Are you sure?', method: :delete %></td> </tr> <% end %> </table> 

And all I need for this model association for the username is to put "@articles = Article.all" on the index action before response_to. Pretty awesome!

What if I want to list all of these articles (I just skipped paging here for the sake of simplicity) on my home page using the index action on my home controller?

I know that I can do something like this in the Home Controller:

 class HomeController < ApplicationController def index @articles = Article.joins(:user) end end 

... and then I can access this data in my home index:

 <div class="row"> <% @articles.each do |article| %> <div> <h3><%= link_to article.title, :controller => "articles", :action => "show", :id => article.id %></h3> <small>Posted on <%= article.created_at %> by <a href="#"><%= article.user.name %></a></small> </div> <% end %> </div> 

First question: When accessing user data for all articles, should I use: join or a: includes? They both seem to work, but I wonder which one is right in this situation, and which usually works faster.

 @articles = Article.joins(:user) 

-vs-

 @articles = Article.includes(:user) 

Second question: In my project for the article (creating migration), you should use user_id: integer or user: reference. Do they do the same or prefer each other? If I use: integer as the type of the field, is it recommended that I add an index for it (add_index: articles ,: user_id)? I found a great RailsCast and it does a great job explaining, but I'm wondering if anyone has a different opinion.

If this helps, I'm on Rails 3.2.2.

Thanks!

+6
source share
2 answers

First question:

You want to get all articles with your users data in an efficient way, you should use

 @articles = Article.includes(:user) 

You will receive a list of all the articles in your database, each article with an already uploaded user.

With @articles = Article.joins(:user) you only get articles that have a User, and when you do article.user in any of these articles, it will generate a new SQL query.

For more information: http://guides.rubyonrails.org/active_record_querying.html (if you have not read this set of manuals, I highly recommend that you do it now).

Second question:

I use the form user_id:integer . I am not sure if user:references can be used on the rails g scaffold command line. The index in the column "articles.user_id" will improve the search speed when searching for articles by a specific user. Add this index only if your application will perform this search.

+3
source
  • You should use @articles = Article.all :include => :user to retrieve the entries. Read Rails: include vs .: join for more information on why this is usually faster than :joins . (Basically, it gives you the same information without duplicates.)

  • Rails has a shortcut for belongs_to associations when it comes to migration. Use belongs_to :user , and Rails will automatically include the user_id column (of type integer ) for you.

Example:

 class CreateArticle < ActiveRecord::Migration def self.up create_table :articles do |t| t.belongs_to :user # Creates 'user_id' column t.timestamps end end end 
+5
source

Source: https://habr.com/ru/post/907060/


All Articles