0
votes

Good Day,

Excuse me for the noob question.

In my rails app I have /YYYY/MM/DD/Title-Slug URL structure with Friendly_Id .

news_controller.rb

class NewsController < ApplicationController
before_action :set_news, only: [:show, :edit, :update]
before_action :authenticate_user!, except: [:show, :index, :search ]
def index
if params[:search]

   @news = News.search(params[:search]).paginate(:page => params[:page],  :per_page => 12).order("created_at DESC")

 else
@news = News.where( state: true ).paginate(:page => params[:page],  :per_page => 12).order('id DESC')
end
end

def latest_news



if current_user.admin?
@news = News.paginate(:page => params[:page],  :per_page => 12).order('id DESC')
else
 flash[:error] = "you are not authorised to visit this section"
redirect_to root_path
end 

end 

def new
if current_user.state == true
  @news = News.new
 else
  flash[:error] = "your account has not been activated"
  redirect_to root_path
 end

end

 def show
 @news_photos = @news.news_photos

 end



  def create
    @news = News.new(news_params)
    respond_to do |format|
    if @news.save
      if params[:images]
        params[:images].each do |image|
          @news.news_photos.create(image: image)
        end
      end

      @news_photos = @news.news_photos


      format.html { redirect_to show_news_path(@news.year,@news.month,@news.date,@news ), notice: 'News was successfully created.' }
      format.json { render :show, status: :created, location: @news }

    else
      render :new
    end
  end
  end

  def edit
     @news_photos = @news.news_photos
  end

   def update
      respond_to do |format|
      if current_user.admin?
        if @news.update(admin_news_params)

         if params[:images]
            params[:images].each do |image|
            @news.news_photos.create(image: image)
            end
          end

        #redirect_to root_path, notice: "Updated..."
       # redirect_to latest_news_path, notice: "Updated..."
         format.html { redirect_to show_news_path(@news.year,@news.month,@news.date,@news ), notice: 'News was successfully edited' }
        # format.json { render :show, status: :created, location: @news }
        else
         render :edit
        end
      else  
        if @news.update(news_params)
          if params[:images]
            params[:images].each do |image|
            @news.news_photos.create(image: image)
            end
          end
        #  redirect_to news_index_path, notice: "Updated..."
          #redirect_to latest_news_path, notice: "Updated..."
           format.html { redirect_to show_news_path(@news.year,@news.month,@news.date,@news ), notice: 'News was successfully edited.' }
        #   format.json { render :show, status: :created, location: @news }
        else
          render :edit
        end
      end
    end
   end


  def destroy
    @news = News.find(params[:id])
    @news.destroy

    respond_to do |format|
      format.html { redirect_to news_index_path }
     # format.json { head :no_content }
   end
 end







private
  def set_news
    @news = News.find(params[:id])
  end 

def news_params
    params.require(:news).permit( :title, :description, :category, :keywords, :user_id, :email, :user_name)
end
def admin_news_params
    params.require(:news).permit( :title, :description, :category, :keywords, :user_id, :email, :user_name, :state)
end


end

news_helper.rb

module NewsHelper
  def show_news_path(news)
    "/news/#{news.year}/#{news.month}/#{news.date}/#{news.slug}"
  end

end

news.rb

class News < ApplicationRecord
extend FriendlyId
 include PgSearch
 has_many :news_photos
friendly_id :slug_candidates, use: [:slugged, :finders, :history]

 def slug_candidates 
  [ :title,
   [:title, :id]
   ] 
end

def year
    created_at.localtime.strftime("%Y")
  end

  def month
    created_at.localtime.strftime("%m")
  end

  def date
    created_at.localtime.strftime("%d")
  end

end

routes.rb

Rails.application.routes.draw do

resources :news, :except => [:latest_news, :search, :show, :edit, :update]

 root :to => "news#index"

 scope 'news' do

   get     '/:year/:month/:date/:id',      to: 'news#show',   as: 'show_news'

    get     '/:year/:month/:date/:id/edit', to: 'news#edit',   as: 'edit_news'

    patch   '/:year/:month/:date/:id',      to: 'news#update'
    put     '/:year/:month/:date/:id',      to: 'news#update'
    delete  '/:year/:month/:date/:id',      to: 'news#destroy'
  end



end

_form.html.erb

<div class="row">
  <div class="col-md-8 col-md-offset-2">
    <%= form_for @news, :html => { :class => 'form-horizontal', multipart: true } do |f| %>
      <div class="row">
          <div class="col-md-12">
            <%= f.label :title, :class => 'control-label' %>
            <div class="form-group">
              <%= f.text_field :title, :class => 'form-control' %>
            </div>  
          </div>
        </div>
        <div class="row">
          <div class="col-md-12">
            <%= f.label :keywords, :class => 'control-label' %>
            <div class="form-group">
              <%= f.text_field :keywords, :class => 'form-control' %>
            </div>
          </div>  
        </div>  
         <div class="row">
          <div class="col-md-12">
            <%= f.label :description, :class => 'control-label' %>
            <div class="form-group">
              <%= f.text_area :description, :class => 'form-control', id: "input" %>
            </div>
          </div>  
        </div>

        <div class="row">
          <div class="col-md-12">
            <label>Upload Image</label>
            <div class="form-group">
              <span class="btn btn-success btn-file">
                  <i class="fa fa-cloud-upload fa-lg"></i> Upload Photos
                    <%= file_field_tag "images[]", type: :file, multiple: true %>
              </span>    
            </div>
          </div>  
        </div>

        <div class="row">
          <div class="col-md-6 col-md-offset-3">
            <%= f.submit nil, :class => 'btn btn-info' %>
          </div>
        </div>  
    <% end %>
  </div>
</div>    

here's what works:

  • news/index

  • /news/2017/4/27/example

  • Creating a new post
  • Destroying a post

What doesn't work:

Editing a post (the edit page with the form will render, but after submitting my changes i am getting the aforementioned error - and the changes never make it to the DB)

error:

ActionController::RoutingError (No route matches [PATCH] "/news/example"):

I have fallowed the below post to implement the date based slugs: /YYYY/MM/Title-Slug URL structure with Friendly_Id Solution Chokes on #edit

I DONT UNDERSTAND WHAT I HAVE GONE WRONG IN news_helper.rb

Any help is Highly Appreciated.Thanks in Advance

2

2 Answers

1
votes

try below code:

Rails.application.routes.draw do

resources :news, :except => [:latest_news, :search, :show, :edit]

remove :update from except

1
votes

It's because you've disabled the update action in your routes

resources :news, :except => [:latest_news, :search, :show, :edit, :update]

The solution is to allow the update by removing it from the except clause like this

resources :news, except: [:latest_news, :search, :show, :edit]

The user will never see this url unless they "view-source" it so it doesn't matter for usability sake.