【问题标题】:I want to show grandchildren records under grandparents show page... what am I doing wrong?我想在祖父母显示页面下显示孙子记录......我做错了什么?
【发布时间】:2020-02-28 14:27:57
【问题描述】:

在我的代码中,用户有学生,学生有日记,日记有 diary_entries。我想在学生展示页面下显示每个学生的日记条目。以下是我的模型。

Student.rb 模型

class Student < ApplicationRecord
  belongs_to :user
  has_many :diaries, dependent: :destroy
  has_many :teams, dependent: :destroy
  has_many :subjects, dependent: :destroy
  belongs_to :grade

  accepts_nested_attributes_for :diaries
  accepts_nested_attributes_for :subjects
  accepts_nested_attributes_for :teams
end

Diary.rb 模型

class Diary < ApplicationRecord
    belongs_to :student
    belongs_to :user
    belongs_to :grade
    has_many :diary_entries

    validates :diary_year, presence: true

    def self.from_student(owner, student_obj)
        new(
            user_id: owner.id,
            student_id: student_obj.id,
            grade_id: student_obj.grade_id,
            diary_year: Date.today.year
        )
    end

end

Diary_entry.rb 模型

class DiaryEntry < ApplicationRecord
  belongs_to :diary
  belongs_to :subject
  belongs_to :user

  validates :lesson_date, :assignment, :assignment_due_date, :notes_to_parents, presence: true
end

日记控制器

class DiariesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_student

  def create
    @diary = Diary.from_student(current_user, @student)
    @diary.save
    redirect_to @student, notice: "Diary was successfully created."

  end

  private

  def set_student
    @student = Student.find(params[:student_id])
  end
end

学生控制器#show

 def show
    @diary = @student.diaries
    @diary_entries = @diary.diary_entries
  end

Diary_entries 控制器#index 和 Show

  def index
    @diary_entries = @diary.diary_entries.all
  end

  def show
    @diary_entry = DiaryEntry.find(params[:id])
  end

我希望每个学生每年只有 1 篇日记,因此我在每个日记中添加了 diary_year 列,然后在日记表上添加了 student_id 和 year 的唯一索引。

  create_table "diaries", force: :cascade do |t|
    t.bigint "user_id"
    t.bigint "student_id"
    t.bigint "grade_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "diary_year"
    t.index ["grade_id"], name: "index_diaries_on_grade_id"
    t.index ["student_id", "diary_year"], name: "index_diaries_on_student_id_and_diary_year", unique: true
    t.index ["student_id"], name: "index_diaries_on_student_id"
    t.index ["user_id"], name: "index_diaries_on_user_id"
  end

以下是我在学生展示页面中尝试的循环。

<div class="card">
   <div class="card-body">

     <% @diary_entries.each do |entry| %>
       <li><%= entry.assignment %></li>
     <% end %>
   </div>
 </div>

我希望能够 1. 让每个学生每年只有 1 篇日记,2. 在每个学生页面下显示 diary_entries。

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    你想显示diary_entriesStudent,使用joins

    @diary_entries = DiaryEntry.joins(diary: :student)
                               .where(students: { id: @student.id })
    

    有关联接的更多信息 - https://guides.rubyonrails.org/active_record_querying.html#joins

    试一试!

    【讨论】:

    • 像魔术一样工作......经过 3 天的尝试,我很难相信这就是它的全部内容。 :)
    【解决方案2】:
    1. 让每个学生每年只写一篇日记,

    要每年强制执行一个 Diary 对象,您可以在 Diary 模型中添加 before_validation。见Callbacks

    回调应该调用一个私有函数来检查可能冲突的现有记录。

    def ensure_valid_year
      return unless student.diaries.where(diary_year: diary_year).any?
      # code or function call here to handle rejection of the new Diary object
    end
    
    1. 在每个学生页面下显示 diary_entries。

    您可以在 Student 模型中添加另一个关系。

    has_many :diary_entries, through: :diaries
    

    您可以像这样访问相关的 DiaryEntry 对象:

    student1 = Student.first
    student1.diary_entries
    

    【讨论】:

    • @samgichuru 我也鼓励你使用 has_many 关系。它延迟加载,因此不会导致任何减速。在您的控制器中,您可以使用 @diary_entries = @student.diary_entries 访问它
    • 哇,这也太神奇了 :) - 希望我能同时接受/标记为最佳,两个答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2022-08-22
    • 2016-03-29
    • 1970-01-01
    相关资源
    最近更新 更多