Mat*_*ieu 7 ruby activerecord ruby-on-rails devise ruby-on-rails-4
我在Rails 4应用程序上有一个ruby,使用设计和用户模型以及交易模型.
我正在user_deals
为User和Deal之间的has_many/has_many关系创建一个表.
这是迁移
class CreateUserDeals < ActiveRecord::Migration
def change
create_table :user_deals do |t|
t.belongs_to :user
t.belongs_to :deal
t.integer :nb_views
t.timestamps
end
end
end
Run Code Online (Sandbox Code Playgroud)
当用户加载一个Deal(例如Deal id = 4)时,我使用一个名为的方法 show
controllers/deal.rb
#for the view of the Deal page
def show
end
Run Code Online (Sandbox Code Playgroud)
在这个Deal id = 4页面的视图中,我需要current_user
在用户当前所在的Deal页面中显示Devise的视图.
deal/show.html
here is the nb of views of user: <% current_user.#{deal_id}.nb_views%>
Run Code Online (Sandbox Code Playgroud)
让我们说我有10M + user_deals
线,我想知道我是否应该使用索引
add_index :user_deals, :user_id
add_index :user_deals, :deal_id
Run Code Online (Sandbox Code Playgroud)
或者可能
add_index(:deals, [:user_id, deal_id])
Run Code Online (Sandbox Code Playgroud)
确实在其他情况下我会说是,但在这里我不知道Rails如何在幕后工作.感觉好像Rails是知道的,而不需要我来加快这一进程,......该怎么办,就好像当Rails的负载这种观点是没有SQL查询(如"找到的意见处,NB user_id= x
和deal_id= Y
"). ...因为我只是用于current_user
登录的人(通过设计current_user
)并且deal_id
Rails知道它,因为我们在这个交易的页面(显示页面)所以我只是将它作为参数传递.
那么我需要一个索引来加速它吗?
你关于索引的问题是一个很好的问题。导轨确实会生成 SQL* 来发挥其魔力,因此优化数据库的常规规则适用。
devise 的魔力仅适用于 current_user。它使用 SQL 查询获取详细信息,这是高效的,因为 devise 创建的用户表默认具有有用的索引。但这些不是您需要的索引。
首先,有一种更简洁、更惯用的方式来完成您想要的事情
class CreateUserDeals < ActiveRecord::Migration
def change
create_join_table :users, :deals do |t|
t.integer :nb_views
t.index [:user_id, :deal_id]
t.index [:deal_id, :user_id]
t.timestamps
end
end
end
Run Code Online (Sandbox Code Playgroud)
您会注意到迁移包括两个索引。如果您从未期望为给定交易创建所有用户的视图,那么您将不需要这些索引中的第二个。然而,正如 @chiptuned 所说,对每个外键建立索引几乎总是正确的选择。整数索引只消耗很少的写入资源,但在读取方面却节省了大量资源。这是一个成本非常低的默认防御位置。
如果您将数据获取逻辑放入控制器中,您将会度过一段更好的时光,并且事情会感觉更清晰。此外,您正在展示一项交易,因此您会觉得这样做是正确的,而不是current_user
,因此将其作为数据获取的中心
实际上,您可以在不使用through
关联的情况下执行此查询,因为您可以在不接触用户表的情况下执行此查询。through
(不过,您可能会希望在其他情况下建立这种关联。)has_many :user_deals
就可以完成这项工作。
为了最好地利用数据库引擎并在一个查询中执行此操作,您的控制器可以如下所示:
def show
@deal = Deal.includes(:user_deals)
.joins(:user_deals)
.where("user_deals.user_id = ?", current_user.id)
.find(params["deal_id"])
end
Run Code Online (Sandbox Code Playgroud)
那么在你看来...
I can get info about the deal: <%= @deal.description %>
Run Code Online (Sandbox Code Playgroud)
并感谢includes
我可以获取用户 nb_views 而无需单独的 SQL 查询: <%= @deal.user_deals.nb_views %>
* 如果你想看看 SQL Rails 神奇地生成了什么,就放在.to_sql
最后。例如sql_string = current_user.deals.to_sql
或@deal.to_sql
归档时间: |
|
查看次数: |
1941 次 |
最近记录: |