Dodawanie, edytowanie i usuwanie komentarzy tylko przez użytkowników, którzy je utworzyli

Witam wszystkich,
Tworze aplikacje podobną do pinterestu lub polskiej zszywki. Chciałabym dodać do aplikacji funkcjonalność polegająca na dodawaniu komentarzy do obrazków (pinów) przez zalogowanych użytkowników. Chciałabym również aby tylko autorzy komentarzy mogli je edytować lub usuwać, natomiast inni użytkownicy (zalogowani jak i nie) mogli je jedynie oglądać. Właściwie to mam problem z konrolerem dla komentarzy, który wygląda tak:

class ComsController < ApplicationController

def create
@pin = Pin.find(params[:pin_id])
@com = @pin.coms.create(params[:com].permit(:content))
@com.user_id = current_user.id if current_user
@com.save

  if @com.save
      redirect_to pin_path(@pin)
  else
      render 'new'
  end

end

def edit
@pin = Pin.find(params[:pin_id])
@com = @pin.coms.find(params[:id])
end

def update
@pin = Pin.find(params[:pin_id])
@com = @pin.coms.find(params[:id])

if @com.update(params[:com].permit(:content))
  redirect_to pin_path(@pin)
else
  render 'edit'
end

end

def destroy
@pin = Pin.find(params[:pin_id])
@com = @pin.coms.find(params[:id])
@com.destroy
redirect_to pin_path(@pin)
end

end

Natomiast tak wygląda kontroler dla pinów:
class PinsController < ApplicationController
before_action :set_pin, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
before_action :correct_user, only: [:edit, :update, :destroy]

GET /pins

GET /pins.json

def index
@pins = Pin.all.order(“created_at DESC”).paginate(:page => params[:page], :per_page => 25)
end

GET /pins/1

GET /pins/1.json

def show

end

GET /pins/new

def new
@pin = current_user.pins.build
end

GET /pins/1/edit

def edit
end

POST /pins

POST /pins.json

def create
@pin = current_user.pins.build(pin_params)

respond_to do |format|
  if @pin.save
    format.html { redirect_to pins_path, notice: 'Pin utworzony pomyślnie.' }
    format.json { render :show, status: :created, location: @pin }
  else
    format.html { render :new }
    format.json { render json: @pin.errors, status: :unprocessable_entity }
  end
end

end

PATCH/PUT /pins/1

PATCH/PUT /pins/1.json

def update
respond_to do |format|
if @pin.update(pin_params)
format.html { redirect_to @pin, notice: ‘Pin zmieniony pomyślnie.’ }
format.json { render :show, status: :ok, location: @pin }
else
format.html { render :edit }
format.json { render json: @pin.errors, status: :unprocessable_entity }
end
end
end

DELETE /pins/1

DELETE /pins/1.json

def destroy
@pin.destroy
respond_to do |format|
format.html { redirect_to pins_url, notice: ‘Pin usunięty pomyślnie.’ }
format.json { head :no_content }
end
end

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

# Never trust parameters from the scary internet, only allow the white list through.
def pin_params
  params.require(:pin).permit(:title, :description, :image, :login)
end

def correct_user
@pin = current_user.pins.find_by(id: params[:id])
redirect_to pins_path, notice: “Nie jesteś uprawniony do edycji tego pinu” if @pin.nil?
end

end

System logowania jest utworzony za pomocą gemu devise i działa poprawnie z rusztowaniem dla pinów.
Będę wdzięczna za każdą pomoc :wink:

Taki system kontroli tego, co kto może zrobić to autoryzacja i jest kilka gemów do tego https://www.ruby-toolbox.com/categories/rails_authorization.html
Każdy z nich robi to inaczej.

A nie wystarczy ograniczyc w widoku
if @pin.user == current_user?

Samo niewyświetlenie przycisku? User i tak mógłby wysłać request, jeśli wie, jak działają mniej więcej aplikacje Rails.

Racja. W kontrolerze niech tak zrobi i powinno dzialac.

  1. Na froncie pokazujesz przycisk do edycji/usunięcia komentarza dla przycisku
  2. Na backendzie, robisz walidację, czy edytowany komentarz należy do użytkownika

Do helpera dla komentarzy wrzuć sobie metodę np:
def comment_owner?
# warunek sprawdzający przynależność np:
@current_user == @comment.owner
end
i w widoku
<% if comment_owner? %>
show edit and destroy btn
<% end %>
Możesz też użyć tej metody w kontrolerze (choć nie jestem pewny czy to dobra praktyka):
helper_method: :comment_owner?

def action
if current_owner?
edit/destroy_comment
else
flash = ‘Comment doesn’t belong to you’
end
end

Używanie helperów, w ogóle, to słaba praktyka, a do autoryzacji zasobów to już szaleństwo. Najlepiej zainteresować się https://github.com/elabs/pundit