Rails中的文章/帖子草稿

时间:2016-07-23 17:11:26

标签: ruby-on-rails ruby

我正在开发一个可公开编辑的Rails中的wiki应用程序。我有一个物品控制器和一个草稿控制器。当有人点击“编辑”时在一篇文章中,我想创建一个包含原始文章内容的新草稿,然后在用户点击“保存”时将其保存到数据库表中。关于我如何做到这一点的任何想法?我已经坚持了几天。

目前,每篇文章都属于一个类别,一个子类别和has_many草稿。

数据库架构:

ActiveRecord::Schema.define(version: 20160723153357) do

  create_table "articles", force: :cascade do |t|
    t.datetime "created_at",     null: false
    t.datetime "updated_at",     null: false
    t.string   "title"
    t.text     "content"
    t.integer  "category_id"
    t.integer  "subcategory_id"
  end

  create_table "categories", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "drafts", force: :cascade do |t|
    t.string   "title"
    t.text     "content"
    t.integer  "category_id"
    t.integer  "subcategory_id"
    t.integer  "article_id"
    t.datetime "created_at",     null: false
    t.datetime "updated_at",     null: false
  end

  create_table "subcategories", force: :cascade do |t|
    t.string   "name"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.integer  "category_id"
  end

end

Articles_controller:

class ArticlesController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :destroy]

  # GET /articles
  # GET /articles.json
  def index
    if params[:category].blank? && params[:subcategory].blank?
      @articles = Article.all.order("created_at DESC")
    elsif params[:subcategory].blank?
      @category_id = Category.find_by(name: params[:category]).id
      @articles = Article.where(category_id: @category_id).order("created_at DESC")
    else
      @subcategory_id = Subcategory.find_by(name: params[:subcategory]).id
      @articles = Article.where(subcategory_id: @subcategory_id).order("created_at DESC")
    end
  end

  # GET /articles/1
  # GET /articles/1.json
  def show
  end

  # GET /articles/new
  def new
    @article = Article.new
  end

  # GET /articles/1/edit
  def edit
  end

  # POST /articles
  # POST /articles.json
  def create
    @parameters = article_params
    @parameters[:category] = Category.find_by(id: Subcategory.find_by(id: article_params[:subcategory_id]).category_id)
    @article = Article.new(@parameters)

    respond_to do |format|
      if @article.save
        format.html { redirect_to @article, notice: 'Article was successfully created.' }
        format.json { render :show, status: :created, location: @article }
      else
        format.html { render :new }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /articles/1
  # PATCH/PUT /articles/1.json
  def update
    respond_to do |format|
      if @article.update(article_params)
        format.html { redirect_to @article, notice: 'Article was successfully updated.' }
        format.json { render :show, status: :ok, location: @article }
      else
        format.html { render :edit }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /articles/1
  # DELETE /articles/1.json
  def destroy
    @article.destroy
    respond_to do |format|
      format.html { redirect_to articles_url, notice: 'Article was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_article
      @article = Article.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def article_params
      params.require(:article).permit(:title,:content,:subcategory_id)
    end
end

Drafts_controller:

class DraftsController < ApplicationController
  before_action :set_draft, only: [:show, :edit, :update, :destroy]

  # GET /drafts
  # GET /drafts.json
  def index
    @drafts = Draft.all
  end

  # GET /drafts/1
  # GET /drafts/1.json
  def show
  end

  # GET /drafts/new
  def new
    @draft = Draft.new
  end

  # GET /drafts/1/edit
  def edit
  end

  # POST /drafts
  # POST /drafts.json
  def create
    @parameters = draft_params
    @parameters[:article_id] = params[:article_id]
    @parameters[:subcategory_id] = 2
    @parameters[:category_id] = 2
    @draft = Draft.new(@parameters)

    respond_to do |format|
      if @draft.save
        format.html { redirect_to @draft, notice: 'Draft was successfully created.' }
        format.json { render :show, status: :created, location: @draft }
      else
        format.html { render :new }
        format.json { render json: @draft.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /drafts/1
  # PATCH/PUT /drafts/1.json
  def update
    respond_to do |format|
      if @draft.update(draft_params)
        format.html { redirect_to @draft, notice: 'Draft was successfully updated.' }
        format.json { render :show, status: :ok, location: @draft }
      else
        format.html { render :edit }
        format.json { render json: @draft.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /drafts/1
  # DELETE /drafts/1.json
  def destroy
    @draft.destroy
    respond_to do |format|
      format.html { redirect_to drafts_url, notice: 'Draft was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_draft
      @draft = Draft.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def draft_params
      params.require(:draft).permit(:title, :content)
    end
end

文章模型:

class Article < ApplicationRecord
  belongs_to :category
  belongs_to :subcategory
  has_many :drafts
end

草稿模型:

class Draft < ApplicationRecord
  belongs_to :category
  belongs_to :subcategory
  belongs_to :article
end

1 个答案:

答案 0 :(得分:0)

我认为我可能会遵循的方法是将内容信息完全提取到另一个表中。这是我可以立即提出的粗略实现:

class Article < ApplicationRecord
  #column_names: ['type:string']
  has_many :contents
  has_one :current_content, -> { current.or(approved) }, class_name: 'Content'
  delegate :title, :content, to: :current_content, allow_nil: true
end

class Content < ApplicationRecord
  #column_names: ["article_id:int", "title:string", "content:text", "status:int"]
  belongs_to :article
  enum status: [:unapproved, :approved, :current]
end

class Draft < Article
  #use STI here
end

#services/set_current_article_content.rb
class SetCurrentArticleContent
  attr_reader :article, :content
  def initialize(article, content)
    @article = article
    @content = content
  end

  def call
    article.current_content.approved!
    content.current!
  end
end

#services/edit_wiki_content.rb
class EditWikiContent.rb
  attr_reader :article, :content
  def initialize(article, content)
    @article = article
    @content = content
  end

  def call
    article.contents << content
    content.save!
  end
end

#services/publish_draft.rb
class PublishDraft
  attr_reader :draft
  def initialize(draft)
    @draft = draft
  end

  def call
    draft.becomes!(Article)
  end
end

有三种服务可以处理当前内容的更新和设置,也可以发布草稿,您可以在其中任何一种中添加一些额外的逻辑。另请注意文章模型中current_content的条件,您的逻辑可能与我实现它的方式不同。