我正在开发一个可公开编辑的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
答案 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的条件,您的逻辑可能与我实现它的方式不同。