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.