当我将belongs_to:user添加到/app/models/article.rb时,无法在文章中发帖

时间:2017-10-08 02:51:34

标签: ruby-on-rails devise

我浏览了Rails教程(http://guides.rubyonrails.org/getting_started.html)并创建了一篇文章模型。我没有将评论部分添加到我的应用程序中。我设置了Devise来处理用户。

效果很好,用户可以创建,编辑和销毁其他帖子。我现在想让用户只编辑或删除他们自己的文章帖子。

我做了一些更改,当任何用户尝试创建文章帖时,我收到错误“用户必须存在”。我注意到添加belongs_to:user是创建此错误的原因。有办法解决这个问题吗?

我添加了一个引用和外键:

rails g migration AddUserToUploads user:references

然后我确定我迁移了这个:

class AddUserToArticles < ActiveRecord::Migration[5.0]
  def change
    add_reference :articles, :user, foreign_key: true
  end
end

我将'belongs_to:user'添加到了app / models / article.rb,所以它看起来像:

class Article < ApplicationRecord
  validates :title, presence: true,
                    length: { minimum: 5 }

  belongs_to :user

end

我的app / models / user.rb现在看起来像这样:

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :lockable, :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :articles
end

我在视图中暂时禁用了任何用户限制。

我的articles_controller.rb设置如下:

class ArticlesController < ApplicationController

  def index
    @articles = Article.all
    if params[:search]
      @articles = Article.search(params[:search]).order("created_at DESC")
    else
      @articles = Article.all.order('created_at DESC')
    end
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def edit
    @article = Article.find(params[:id])
  end

  def create
    @article = Article.new(article_params)
    if @article.save
      redirect_to @article
    else
      render 'new'
    end
  end

  def update
    @article = Article.find(params[:id])

    if @article.update(article_params)
      redirect_to @article
    else
      render 'edit'
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.destroy

    redirect_to articles_path
  end

  private
    def article_params
      params.require(:article).permit(:title, :text, :description, :keyword, :syntax, :programlang)
    end

我已尝试将destroy方法更改为此但仍然无法执行任何操作:

  def destroy
    @article = Article.find(params[:id])
    if user_signed_in? && current_user.articles.exists?(@article.id)
      @article.destroy
    else
      redirect_to articles_path
    end
  end

我错过了什么吗?我需要对我的文章做出哪些更改?

2 个答案:

答案 0 :(得分:0)

您可以尝试在控制器上放置多个before_action,如下所示:

class ArticlesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_post,         only: [:edit, :update, :destroy]
  before_action :check_post_owner, only: [:edit, :update, :destroy]

  def edit
    # just leave this blank - it's fine
  end

  def update
    if @article.update(article_params)
      redirect_to @article
    else
      render 'edit'
    end
  end

  def destroy
    @article.destroy
    redirect_to articles_path
  end

  private

  def set_post
    @article = Article.find(params[:id])
  end

  def check_post_owner
    if @article.user != current_user
      flash[:notice] = "You're not the owner"
      redirect_to articles_path
    end
  end

end

:authenticate_user!是Devise方法。 set_postcheck_post_ownerprivate部分内的自定义方法。

您还可以通过创建方法重构@article = Article.find(params[:id])行,并在我的before_action方法内部set_post调用它。

答案 1 :(得分:0)

在Rails 5中,你需要在你的子模型中添加required = false,以便在你不通过关联方法创建子记录时创建子记录

 class Article < ApplicationRecord
  validates :title, presence: true,
                length: { minimum: 5 }

  belongs_to :user, required: false

 end

干杯!