简体   繁体   中英

Adding Favorite to Just the User logged in, not all Users

I am working on creating a favorite method with Rails backend and a React front end. Im attempting to allow the user to select a coffee shop and favorite it in order to add it to their own favorites list. My method seems to be working as far it being added, however when the users adds the coffee shop all users can see it in their favorites instead of just the specific users being able to see it in their own favorites list...

my Favorite Controller...

class FavoritesController < ApplicationController
    before_action :authorized, only:[:create, :update]
    def index
        favorites = Favorite.all 
        render json: favorites
    end

    def show
        favorite = Favorite.find_by(params[:id])
        render json: favorite
    end

    def create
        coffee_shop = CoffeeShop.find_or_create_by(:name => params[:coffee_shop_name]) do |coffee_shop|
            coffee_shop.image_url = params[:coffee_shop_image_url]
            coffee_shop.phone = params[:coffee_shop_phone]
        end
        favorite = Favorite.new
        favorite.user_id = @user.id
        favorite.coffee_shop_id = coffee_shop.id
        favorite.save
        render json: favorite
    end
  
    def update
        favorite = Favorite.find(params[:id])
        favorite.update(favorite_params)
        favorite.save
        render json: favorite
    end

    def destroy
        favorite = Favorite.find(params[:id])
        favorite.destroy
        render json: {message: "Successfully removed favorite"}
    end

    private

    def favorite_params
        params.require(:favorite).permit(:coffee_shop_id, :user_id, :coffee_shop_image_url)
    end
end

My Favorites code component/container

import React from 'react'


class Favorite extends React.Component {
    
    state = {
    favorites:[],
    cafes:[],
    }
   

   handleDelete = (e) =>{
    const cafedelete = {
        coffee_shop_name: this.state.coffee_shop_name,
        coffee_shop_image_url: this.state.coffee_shop_image_url,
        coffee_shop_phone: this.state.coffee_shop_phone,
        coffee_shop_id: this.state.coffee_shop_id,
      }  
     this.props.removeFav(cafedelete)
    }
   
   render() {
       console.log(this.state.cafes.name)
        return (
        <div className="fav-card">
            <ul className="fav-ul">
             <img src={this.props.favorite.coffee_shop.image_url} className="fav-img"alt="cafe"></img>
            <div>{this.props.favorite.coffee_shop.name}</div>
        <div>{this.props.favorite.coffee_shop.phone}</div>
        {/* <button onClick={(e) => {this.handleDelete(e)}}>X</button> */}
        </ul>
        </div>
            )
        }
    }
    export default Favorite;

-------
import React from 'react';
import CoffeeShop from './CoffeeShop'
import NavBar from './NavBar'
// import coffeecup from './coffeecup.png'

class CafesContainer extends React.Component {

  state = {
    cafes: [],
    cafe:{},
    isCafeViewOn: false,
    inputValue: '',
    inputSort: '',
}

componentDidMount() {
  fetch("http://localhost:3000/search")
  .then(resp => resp.json())
  .then(cafes => this.setState({ cafes: cafes.businesses }))
}

addToFav = (cafe) => {
  console.log(cafe)
  fetch(`http://localhost:3000/favorites`,{
    method: "POST",
    headers: { 
      "Content-Type" : "application/json",
      Accept: "application/json",
      Authorization: `bearer ${localStorage.token}`
    },
      body: JSON.stringify( cafe )
  })
  .then(res => res.json())
  .then(console.log)
  }
  cafeFilterOnChange = (e) => {
    console.log (e.target.value)
    this.setState({
      inputValue: e.target.value,
      inputSort: e.target.value,
    });
  };


  
render() {  
  
  const filteredCafes =
  this.state.cafes.filter( cafe => {
    return cafe.name.toLowerCase().includes(this.state.inputValue.toLowerCase())
  })

  console.log(this.state.cafes)
    return (
      <div className="cafe-title"> 
       {/* <img className="cup" src={coffeecup} alt="cup" /> */}
       <NavBar />
      <label className="cafe-search"htmlFor="search">Search by Cafe Name</label>
      <br></br>
      
      <input type="text" className="cafe-search-bar" placeholder="Type Cafe Name Here..." value={this.inputValue} onChange={(e) => {this.cafeFilterOnChange(e)}}/>

      <ul>
        {
           filteredCafes.map(cafe => <CoffeeShop cafes={this.filteredCafes} handleCafeView={this.handleCafeView} cafeFilterOnChange={this.cafeFilterOnChange} inputValue={this.inputValue}
           addToFav={this.addToFav} key={cafe.id} cafe={cafe} />)
        }  
      </ul>
     </div>
    )
  }
}
;
  export default CafesContainer;

I am using JWT for auth, my ApplicationController...

class ApplicationController < ActionController::API
  # before_action :authorized, only:[:create]
  def encode_token(payload)
      JWT.encode(payload, "coffee")
  end 

def auth_header
  # { Authorization: 'Bearer <token>' }
  request.headers['Authorization']
end

def decoded_token
  if auth_header
    token = auth_header.split(' ')[1]
    # header: { 'Authorization': 'Bearer <token>' }
    begin
      JWT.decode(token,'coffee', true, algorithm: 'HS256')
    rescue JWT::DecodeError
      nil
    end
  end
end

def current_user
  if decoded_token
    user_id = decoded_token[0]['user_id']
    @user = User.find_by(id: user_id)
  end
end

def logged_in?
  !!current_user
end

def authorized
  render json: { message: 'Please log in' }, status: :unauthorized unless logged_in?
end
end

Recent Boot Camp grad, still trying to find my way, if any other info is needed please let me know, any help is appreciated!

I suspect instead of

def index
  favorites = Favorite.all 
  ...

you really want

favorites = current_user.favorites

if you are using authentication (devise eg).

If you haven't added auth yet, you would need to send a user_id param in your fetch.

fetch('http://localhost:3000/favorites?user_id=___')

Then the controller would be

favorites = Favorite.where(user_id: params[:user_id])

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