我坚持从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]]
答案 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%>