Rails 5.0.2 - 无法从许多关系模型中获取数据

时间:2017-05-11 12:42:12

标签: ruby-on-rails

我坚持从3个具有多对多关系的表中获取development.sqlite3中的数据。我可以获得属于给定位置或类别的课程,但它不能解决问题。

我按照课堂上的教学方式,但我认为模型可能已经错过了一些限制。

任何人请看一下并给我一些建议。非常感谢你!

这是我的schema.rb

create_table "categories", force: :cascade do |t|
    t.string   "title"
end

create_table "categories_courses", force: :cascade do |t|
    t.integer "course_id",   null: false
    t.integer "category_id", null: false
end

create_table "courses", force: :cascade do |t|
    t.string   "title"
end

create_table "courses_locations", force: :cascade do |t|
    t.integer "course_id",   null: false
    t.integer "location_id", null: false
end

create_table "locations", force: :cascade do |t|
    t.string   "address"
end

我想获得与给定课程相关联的位置或类别。然后我添加了models中的关系,如下所示:

# Category model
class Category < ApplicationRecord
    has_and_belongs_to_many :courses, join_table: 'categories_courses'
end

# Location model
class Location < ApplicationRecord
    has_and_belongs_to_many :courses, join_table: 'courses_locations'
end

# Course model
class Course < ApplicationRecord
    has_and_belongs_to_many :locations, join_table: 'courses_locations'
    has_and_belongs_to_many :categories, join_table: 'categories_courses'
end

然后在courses_controller.rb中,我获得了这样的位置和类别:

class CoursesController < ApplicationController
    before_action :set_course, only: [:show, :edit, :update, :destroy]

    def categories
        @course = Course.find params[:id]
        @categories = @course.categories
    end

    def locations
        @course = Course.find params[:id]
        @locations = @course.locations
    end

    private

    def set_course
        @course = Course.find(params[:id])
    end
end

最后,我在html.erb文件中显示数据:

<% course.categories.each {|category| puts category.title + ' '} %>
<% course.locations.each {|location| puts location.address + ' '} %>

我很抱歉在这里放了很多代码,但是我应该提供足够的信息来检查代码。

更新

我在route.rb

中有这个
Rails.application.routes.draw do
  resources :locations
  resources :categories
  resources :courses
end

我已根据每个人的建议编辑了代码,但它仍然没有打印任何内容。我注意到查询是正确的,但在rails s控制台中有一个警告:

User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 35], ["LIMIT", 1]]
DEPRECATION WARNING: Passing an argument to force an association to reload is now deprecated and will be removed in Rails 5.1. Please call `reload` on the result collection proxy instead. (called from block in _app_views_courses_index_html_erb___1034719630_104325280 at c:/Users/lovea/RubymineProjects/YourCourse/app/views/courses/index.html.erb:41)
Category Load (0.0ms)  SELECT "categories".* FROM "categories" INNER JOIN "categories_courses" ON "categories"."id" = "categories_courses"."category_id" WHERE "categories_courses"."course_id" = ?  [["course_id", 4]]

3 个答案:

答案 0 :(得分:0)

不确定,但您可能需要添加选项join_table

# Category model
class Category < ApplicationRecord
    has_and_belongs_to_many :courses, join_table: "categories_courses"
end

# Location model
class Location < ApplicationRecord
    has_and_belongs_to_many :courses, join_table: "courses_locations"
end

# Course model
class Course < ApplicationRecord
    has_and_belongs_to_many :locations, join_table: "courses_locations"
    has_and_belongs_to_many :categories, join_table: "categories_courses"
end

答案 1 :(得分:0)

我认为协会应该有效。我自己尝试过并让它在控制台中工作。可能是您与routing有关的问题。

此外,在视图中,而不是:

<% course.categories(course.id).each {|category| puts category.title + ' '} %>
<% course.locations(course.id).each {|location| puts location.address + ' '} %>

你可以:

<% course.categories.each {|category| puts category.title + ' '} %>
<% course.locations.each {|location| puts location.address + ' '} %>

因为关联已经存在而不需要传递id。

答案 2 :(得分:0)

您可以使用集合复选框轻松创建多对多的视图

<%= f.collection_check_boxes(:course_id, Course.all, :id, :title) do |b| %>


   <div class="collection-check-box">
     <%= b.check_box %>
     <%= b.label %>

     <%end%>

     <%= f.submit 'add course to location', class: "btn btn-primary" %>

<%end%>