简体   繁体   中英

how to let users only edit/delete their own items? Ruby on Rails

Need someone's expertise, having a massive headache trying to set users ability to only edit or delete an item(ad) that they have created.

At the moment, I have it as whoever is signed in can edit/delete etc. I had some of the code in place to try the above but I had too many errors, I ended up reverting to my last working build.

index.html.erb

<p id="notice"><%= notice %></p>

 <div id="itemsContainer">



      <% @items.each do |item| %>
      <div class="itemhols">
      <%= link_to (image_tag item.image_url, size: '200x200', :class => "itemholsIm"), item %>
       <h1><%= item.city_country %></h1>
         <p><%= item.title %></p>
       <p>Price per night <%= number_to_currency(item.Price,:unit => "€") %>
       <p>
          <%= link_to 'Show', item %>
       <% if user_signed_in? %>
          <%= link_to 'Edit', edit_item_path(item) %>
          <%= link_to 'Destroy', item, method: :delete, data: { confirm: 'Are you sure?' }%>
       <% end %>
          <a href="/cart/<%= item.id %>" class="button">Add To Cart</a>
       </p>

      </div>
    <% end %>

</div>


<% if user_signed_in? %>
    <%= link_to 'Rent a Home', new_item_path, :class =>"button", :role=>"button" %>
<% end %>

items_controller.rb

class ItemsController < ApplicationController
  before_action :set_item, only: [:show, :edit, :update, :destroy]

  # GET /items
  # GET /items.json
  def index
    @items = Item.all
  end

  # GET /items/1
  # GET /items/1.json
  def show
  end

  # GET /items/new
  def new
    @item = Item.new
  end

  # GET /items/1/edit
  def edit
  end

  # POST /items
  # POST /items.json
  def create
    @item = Item.new(item_params)

    respond_to do |format|
      if @item.save
        format.html { redirect_to @item, notice: 'Item was successfully created.' }
        format.json { render :show, status: :created, location: @item }
      else
        format.html { render :new }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /items/1
  # PATCH/PUT /items/1.json
  def update
    respond_to do |format|
      if @item.update(item_params)
        format.html { redirect_to @item, notice: 'Item was successfully updated.' }
        format.json { render :show, status: :ok, location: @item }
      else
        format.html { render :edit }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /items/1
  # DELETE /items/1.json
  def destroy
    @item.destroy
    respond_to do |format|
      format.html { redirect_to items_url, notice: 'Item was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def item_params
      params.require(:item).permit(:city_country, :title, :image_url, :Price)
    end
end

Any help or direction would be greatly appreciated :)

This is known as authorizing a resource.

Given the following assocations:

class User
  has_many :items
end

class Item
  belongs_to :user
end

Let start by associating the item with a user on creation:

def create
  @item = current_user.items.new(item_params)
  # ...
end

Then lets setup a before_action on :update, :edit, :destroy which checks if the item belongs to the current user and redirects the user if they are not authorized:

class ItemsController < ApplicationController
  before_action :authenticate_user, except: [:show, :index]
  before_action :set_item, only: [:show, :edit, :update, :destroy]
  before_action :authorize_item, only: [:update, :edit, :destroy]

  # ...
  private  
     # ...
     def authorize_item
       unless @item.user == current_user 
         redirect_to items_path, error: 'You are not authorized'
       end
     end
end

Of course you really don't need to be reinventing the wheel here. Use the Pundit or CanCanCan gem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM