2016-07-23 2 views
0

Я работаю над вики-приложением в Rails, который был бы общедоступным для редактирования. У меня есть контроллер статей и контроллер чертежей. Когда кто-то нажимает «редактировать» в статье, я хотел бы создать новый черновик с содержимым исходной статьи, а затем сохранить его в таблице базы данных, когда пользователь нажимает «сохранить». Любые идеи о том, как я могу это сделать? Я застрял на нем несколько дней.Article/post drafts in Rails

В настоящее время каждая статья принадлежит категории, подкатегории и 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

, пожалуйста, напишите какой-нибудь контроллер/код просмотра? – Ven

+0

Мог бы также бросить article.rb и draft.rb тоже. – MarsAtomic

+0

Да, извините, сделано. – Alex

ответ

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 в модели статьи, ваша логика может отличаться от того, как я ее реализовал.