I am new to rails learning coding for fun. My goal is to let a teacher see list all posts made users who have that teacher. Posts belong to users, and users belong to teachers.
Models:
class User < ActiveRecord::Base
belongs_to :teacher
has_many :posts, dependent: :destroy
class Teacher < ActiveRecord::Base
has_many :user_posts, through: :users, source: :posts
class Post < ActiveRecord::Base
belongs_to :user
The teachers controller:
class TeachersController < ApplicationController
before_action :find_teacher, only: [:index]
def index
@posts = @teacher.user_posts
end
private
def find_teacher
@teacher = current_user
end
end
I am struggling with @posts. I keep getting errors for undefined method for `user_posts'. I am wondering what I have done wrong and where to define it.
Schema.rb (just relevant parts)
create_table "teachers", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "teachers", ["email"], name: "index_teachers_on_email", unique: true, using: :btree
add_index "teachers", ["reset_password_token"], name: "index_teachers_on_reset_password_token", unique: true, using: :btree
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "username"
t.string "TeacherEmail"
t.string "teacher"
end
I tried figuring this out all day yesterday and this morning and am truly stuck. Thanks in advance for your time.
Firstly, if User belongs_to :teacher
, the schema of table Users
should have column teacher_id
with integer
type.
t.integer "teacher_id"
Then if Teacher manager many users, you have to define it in Teacher model. Then you can create a method to query for all posts made by users who have that teacher:
class Teacher < ActiveRecord::Base
has_many :users
def user_posts
Post.where(id: users.map(&:id))
end
end
You are missing user model association in teacher model.
class User < ActiveRecord::Base
belongs_to :teacher
has_many :posts, dependent: :destroy
end
class Teacher < ActiveRecord::Base
has_many :users
has_many :posts, through: :users
end
class Post < ActiveRecord::Base
belongs_to :user
end
Two things that strike me:
teacher_id
foreign key on the users
table. You need it for belongs_to
. has_many
in Teacher
not belongs_to
for the association with users. Hint: after a migration, restart the server/console.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.