Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

rails クソコードを簡潔にしたいのですがどうすれば良くなるでしょうか?

いいね機能をposts/showのみではなくindexページでも行えるようにしたいのですが、その際いいねボタンを押すとshowページに遷移されてしまうのを解消しようと思いやったらクソコードが出来上がってしまいました

routes.rb
  get "likes/:post_id/indexcreate" => "likes#indexcreate"
  get "likes/:post_id/indexdestroy" => "likes#indexdestroy"

  get "likes/:post_id/create" => "likes#create"
  get "likes/:post_id/destroy" => "likes#destroy"

likes_controller.rb
class LikesController < ApplicationController
    before_action :authenticate_user
    
    def create
      @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
      @like.save
      redirect_to("/posts/#{params[:post_id]}")
    end
  
    def destroy
      @like = Like.find_by(user_id: @current_user.id, post_id: params[:post_id])
      @like.destroy
      redirect_to("/posts/#{params[:post_id]}")
    end
    
    def indexcreate
      @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
      @like.save
      redirect_to("/posts/index")
    end
  
    def indexdestroy
      @like = Like.find_by(user_id: @current_user.id, post_id: params[:post_id])
      @like.destroy
      redirect_to("/posts/index")
    end


  end
posts/index.html.erb
          <% if @current_user && Like.find_by(user_id: @current_user.id, post_id: post.id) %>
            <%= link_to("/likes/#{post.id}/indexdestroy", {method: "post"}) do %>
              <span class="fa fa-heart liked-btn"></span>
            <% end %>
          <% else %>
            <%= link_to("/likes/#{post.id}/indexcreate", {method: "post"}) do %>
              <span class="fa fa-heart unliked-btn"></span>
            <% end %>
          <% end %>
          <%= @post_like_count[post.id] %>          
posts/show.html.erb
      <% if @current_user && Like.find_by(user_id: @current_user.id, post_id: @post.id) %>
        <%= link_to("/likes/#{@post.id}/destroy", {method: "post"}) do %>
          <span class="fa fa-heart liked-btn"></span>
        <% end %>
      <% else %>
        <%= link_to("/likes/#{@post.id}/create", {method: "post"}) do %>
          <span class="fa fa-heart unliked-btn"></span>
        <% end %>
      <% end %>
      <%= @likes_count %>

最後まで読んでいただきありがとうございます
初心者のため説明が下手ですがよろしくお願いします

0 likes

少しだけですが! 

class LikesController < ApplicationController
  before_action :authenticate_user
  before_action :set_like, only: [:destroy, :indexdestroy]

  def create
    @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
    save_and_redirect_to_post(@like)
  end

  def destroy
    @like.destroy
    redirect_to_post(@like.post_id)
  end

  def indexcreate
    @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
    save_and_redirect_to_index
  end

  def indexdestroy
    @like.destroy
    redirect_to_index
  end

  private

  def set_like
    @like = Like.find_by(user_id: @current_user.id, post_id: params[:post_id])
  end

  def save_and_redirect_to_post(like)
    like.save
    redirect_to_post(like.post_id)
  end

  def redirect_to_post(post_id)
    redirect_to("/posts/#{post_id}")
  end

  def save_and_redirect_to_index
    @like.save
    redirect_to_index
  end

  def redirect_to_index
    redirect_to("/posts/index")
  end
end
  • before_action を使用して、コントローラ内の重複したコードを削除。
  • set_like を使用して、 destroy および indexdestroy アクションでの共通処理を一元化。
  • save_and_redirect_to_post および save_and_redirect_to_index を使用して、 create および indexcreate アクションでの共通処理を一元化。
  • 重複したリダイレクトコードをメソッド化して一元化。
2Like

見たところリダイレクト先が違うだけのようなので、外部から指定する形にすれば良いのかなと思います。

    def create
      @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
      @like.save
      redirect_to(params[:redirect_to])
    end
  
    def destroy
      @like = Like.find_by(user_id: @current_user.id, post_id: params[:post_id])
      @like.destroy
      redirect_to(params[:redirect_to])
    end

直接パスを渡すことに懸念があるなら、適当な文字列とマッピングします。
パラメータではなくリファラーを参照する方法もありそうですね。

さらに「なぜリダイレクトするのか」というのを考えると、おそらく「いいねの表示を更新したい」からだと考えます。
それならば非同期通信にしてJavaScriptで表示を変える方法にすればリダイレクトが不要になるので、純粋にいいねを登録/解除するだけの機能ができあがります。

3Like

ActionController::ActionControllerError in LikesController#create
Cannot redirect to nil!
が発生してしまいます

redirect_to(params[:redirect_to])
が原因みたいなのですが、改善法がわかりません
教えていただけると幸いです。

0Like

create する箇所を集約するのはどうでしょうか。

    def create
        create_filter("/posts/index")
    end
  
    def indexcreate
        create_filter("/posts/#{params[:post_id]}")
    end


private

  def create_filter(redirect_path)
      @like = Like.new(user_id: @current_user.id, post_id: params[:post_id])
      @like.save
      redirect_to(redirect_path)
  end

0Like

Your answer might help someone💌