所以我有3个模型,user.rb,blog.rb,post.rb。
由于某种原因,user_id在用户创建博客后返回nil,而博客实际上并未保存。
模型:
USER.RB --
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable,
:validatable
has_many :subscriptions
has_many :blogs, through: :subscriptions
validates :email, uniqueness: true, presence: true
validates_presence_of :password, on: :create
end
BLOG.RB --
class Blog < ActiveRecord::Base
has_many :subscriptions
has_many :users, through: :subscriptions
has_many :posts
belongs_to :user
scope :for, ->(user) do
if user
Blog.all
end
end
end
POST.RB --
class Post < ActiveRecord::Base
belongs_to :blog
end
控制器
BLOGSCONTROLLER --
class BlogsController < ApplicationController
before_filter :authenticate_user!, only: [:my_blogs]
before_action :set_user
before_action :set_blog, only: [:show, :update, :edit, :destroy]
def index
@blogs.all
end
def new
@blog = @user.blogs.build
end
def create
@blog = @user.blogs.build(blog_params)
if @blog.save
redirect_to new_blog_post_path(@blog, @post), notice: "You've successfully created a blog"
else
render :new
end
end
def my_blogs
@blogs = @user.blogs
end
def show
end
def edit
end
def update
if @blog.update(blog_params)
redirect_to @blog, notice: "Blog succesfully updated."
else
render :edit
end
end
def destroy
@blog.destroy
redirect_to blogs_path, notice: "Your blog has been deleted."
end
private
def set_user
@user = current_user
end
def set_blog
@blog = @user.blogs.find(params[:id])
end
def blog_params
params.require(:blog).permit(:name, :user_id)
end
end
POSTSCONTROLLER --
class PostsController < ApplicationController
before_action :set_post, only: [:show, :update, :destroy, :edit]
before_action :set_blog
def create
@post = @blog.posts.build(posts_params)
# @post.blog.user = current_user
if @post.save
redirect_to blog_post_path(@blog, @post), notice: "Post successfully published."
else
flash[:alert] = "Post could not be published."
render "new"
end
end
def new
@post = @blog.posts.build
end
def show
end
def update
if @post.update(posts_params)
redirect_to [@blog, @post], notice: "Post successfully updated."
else
flash[:alert] = "Post has not been updated."
render "edit"
end
end
def edit
end
def destroy
@post.destroy
flash[:notice] = "Post was deleted."
redirect_to @blog
end
private
def set_post
@blog = Blog.find(params[:blog_id])
@post = @blog.posts.find(params[:id])
end
def set_blog
@blog = Blog.find(params[:blog_id])
rescue ActiveRecord::RecordNotFound
flash[:alert] = "The blog you were looking " +
"for could not be found."
redirect_to root_path
end
def posts_params
params.require(:post).permit(:title, :body, :blog_id)
end
end
我做错了什么?我怎样才能这样做,当用户访问my_blogs页面时,他们会看到他们创建的所有博客?当然,时事通讯必须首先与博客相关联。我在时事通讯表上有一个user_id列。
请指教!
答案 0 :(得分:3)
将用户中的行has_many :blogs, through: :subscriptions
更改为has_many :subscribed_blogs, through: :subscriptions, class_name: "Blog"
,并添加行has_many :blogs
,它应该有效。
您的问题是User
和Blog
之间有两个同名的关联:博客belongs_to :user
和has_many :users, through: :subscriptions
。你可能不想这样做!
在另一个方向,您的用户模型仅定义一个关联:has_many :blogs, through: :subscriptions
。当您致电@user.blogs.build(blog_params)
时,此是使用的关联 - 它将创建新的Blog 和新的订阅,并且外键将保存在Subscription#user_id
和Subscription#blog_id
。 Blog#user_id
被忽略,因为它与这种关联无关。
What you think you have:
User.id = 15
Blog.user_id = 15
What you actually have:
User.id = 15
Subscription: user_id = 15 & blog_id = 9
Blog.id = 9
要获取以前的关联类型(实际使用Blog#user_id
的关联类型),您需要将行has_many :blogs
添加到用户模型 - 否through
。不幸的是,这不起作用,因为现有的has_many... through
关联也称为blogs
,并且您不能有两个具有相同名称的关联。因此,将旧关联重命名为subscribed_blogs
或blog_subscriptions
,您应该没问题。