user_id不能保存在简报模型上

时间:2014-12-02 23:19:49

标签: ruby-on-rails ruby ruby-on-rails-4

所以我有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列。

请指教!

1 个答案:

答案 0 :(得分:3)

简短回答

用户中的行has_many :blogs, through: :subscriptions更改为has_many :subscribed_blogs, through: :subscriptions, class_name: "Blog",并添加行has_many :blogs,它应该有效。

答案很长

您的问题是UserBlog之间有两个同名的关联:博客belongs_to :userhas_many :users, through: :subscriptions。你可能不想这样做!

在另一个方向,您的用户模型仅定义一个关联:has_many :blogs, through: :subscriptions。当您致电@user.blogs.build(blog_params)时,是使用的关联 - 它将创建新的Blog 新的订阅,并且外键将保存在Subscription#user_idSubscription#blog_idBlog#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_blogsblog_subscriptions,您应该没问题。