【问题标题】:Rails/SQL no results show from QueryRails/SQL 查询未显示结果
【发布时间】:2016-05-26 20:50:55
【问题描述】:

版本:CENTOS7、mysql2('>= 0.3.13'、'

index.html.erb

<% @sections.each do |section| %>
    <tr>
        <td><%= section.course_id %></td>
        <td><%= section.term_id %></td>
        <td><%= section.user_id %></td>
    </tr>
<% end %>

部分控制器

class SectionsController < ApplicationController
  before_action :authenticate_account!, except: [:show]

  def index
    @sections =  User.find_by_account_id(current_user).courses
  end

  def show
  end
end

createSections 迁移

class CreateSections < ActiveRecord::Migration
  def change
    create_table :courses do |t|
      t.integer :course_id
      t.timestamps null: false
    end

    create_table :terms do |t|
      t.integer :term_id
      t.timestamps null: false
    end

    create_table :users do |t|
      t.integer :user_id
      t.timestamps null: false
    end

    create_table :sections do |t|
      t.belongs_to :course, index: true
      t.belongs_to :term, index: true
      t.belongs_to :user, index: true
      t.timestamps null: false
    end
  end
end

course.rb 模型

belongs_to :user
has_many :sections
has_many :terms, :through => :sections

term.rb 模型

belongs_to :user
has_many :sections
has_many :courses, :through => :sections

section.rb 模型

belongs_to :course
belongs_to :term
belongs_to :user

user.rb

has_many :sections
has_many :courses, :through => :sections
has_many :terms, :through => :sections
  • 预期结果:列出当前(登录)用户的课程/术语/ID
  • 当前结果:空白

这是我第一次使用 rails 和 SO,我尝试了几次更改关系以查看是否会发生任何变化,但不知道如何解决这个问题。我尝试使用 ActiveRecord:Associations 作为参考。我需要做什么才能完成这项工作?

【问题讨论】:

  • 你正在分配@sections = current_user.courses——你的意思是@sections = current_user.sections吗?
  • 我喜欢你顺便描述你的问题 :thumbsup:
  • 已经有了用户current_user,为什么还要查询用户?
  • 也许我误会了我的意图,当我加载我的 /sections 页面时我想要发生的事情是为了显示当前登录用户的“结果”,即。其中他的 user_id 与 course_id、term_id 匹配。例如,老师会教一些课程,这会显示老师在此页面中教授的课程以及条款。

标签: ruby-on-rails ruby activerecord arel


【解决方案1】:

如果你已经有 current_user 那么你可以直接调用相关模型。

@sections =  User.find_by_account_id(current_user).courses

to 

@sections =  current_user.courses

【讨论】:

  • 所以如果我有:def current_user return unless session[:user_id] @current_user ||= User.find(session[:user_id]) end?
  • 如果你正在使用设计 current_user 已经可用,如果你手动进行身份验证是,你必须定义 current_user 方法。
【解决方案2】:

首先要解决的是,您通常希望为要迁移的每个不同的thing 单独迁移。这是一种约定,可帮助您对更改进行细粒度控制,并有助于保持迁移干净。

但有时,您实际上希望进行“大规模”迁移。您在这里进行了大规模迁移。在大规模迁移的情况下,迁移名称应反映综合目的,因此您可能希望将其命名为 CreateCoreTablesCreateSections 对于创建多个表来说太窄了。您还需要将迁移文件的名称更改为 2016XXXXXXXX_create_core_tables.rb,其中 XXXXXXXXX 保留为之前的值。

接下来,您需要更正您对键的使用(_id 列),因为它们不正确地声明了关联字段,这将导致关联无法工作(或工作不正确)。

相反,你想要这样的东西:

类 CreateCoreTables

create_table :terms do |t|
  t.timestamps
end

create_table :users do |t|
  t.timestamps
end

create_table :sections do |t|
  t.integer :user_id, null: false
  t.integer :term_id, null: false
  t.integer :course_id, null: false
  t.timestamps
end

结束 结束

很难从提供的代码中判断实际预期的关系是什么。值得阅读Active Record Migrations 以确保您了解您想要的关系以及如何描述它们。在进行迁移时,还要不断地重新审视模型关系。这些是应用程序的基石,因此您需要花时间把它们做好。

请记住,对于 ActiveRecord 关系,这些规则将指导您:

  • 如果一个模型拥有另一个模型,请使用has_manyhas_one
  • owned 模型中,使用belongs_to
  • 如果一个模型需要访问另一个模型(但不拥有它),请使用has_many:through 关系
  • 模型之间不能直接存在has_manyhas_one 关系;在这种情况下,您需要一个中间表,其中每个其他表都需要belongs_to

一旦确定了迁移和关系,就可以继续查询。您可以使用Rails Eager Loading 优化查询以同时检索关联。这将满足您当前的功能需求,同时防止出现N+1 query 问题。

@sections =  Section.joins(courses: :terms).where(user: current_user)

当您检索到@sections 后,您可以执行这些类型的操作来获取您想要的数据。 coursesterms 成员是集合,您可以与它们进行交互,就像它们是数组一样:

@sections.each do |section|
  puts "Section: #{section.id}"

  puts "Number of user sections: #{@sections.courses.length}"
  section.courses.each do |course|
    puts "Course: #{course.id}"
  end

  puts "Number of user terms: #{@sections.terms.length}"
  @sections.terms do |term|
    puts "Term: #{term.id}"
  end

  puts "User's email: #{@sections.user.email}"
end    

一旦你掌握了这些,你就掌握了 Rails 的基础知识。一次在一个模型/控制器上工作,以免工作过于复杂;一旦组件像您期望的那样工作,您总是可以添加更多。在进入依赖于它的应用程序的新方面之前,请始终确保您的基础工作正常。

另外,请记住使用 Rails 指南。它们非常有帮助,因此在您学习的过程中,请随时将它们放在手边。 SO 也是一个很好的资源,请确保您提出有针对性的问题,以便获得直接的答案。

【讨论】:

  • @AndrewJung 如果这回答了您的问题,请单击答案旁边的复选标记以接受它。复选标记颜色将变为绿色,表明它已被接受。如果您有任何问题或有新信息,请告诉我,我可以提供更新的答案。
猜你喜欢
  • 2011-10-02
  • 2022-10-20
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 2020-04-27
  • 1970-01-01
相关资源
最近更新 更多