I been trying show association between users and posts tables in rails. My problem is that when a user logs in, he/she should be able to see all of their own posts in my react frontend. However, my frontend request is only able to fetch first record that is related to my current user. This is where I send a fetch request to my backend to get the posts that are related to the user's id.
export default function Profile({currentUser}){
const [posts, setPosts] = useState([])
useEffect(() => {
fetch(`/posts/${currentUser.id}`)
.then((r) =>{
if(r.ok){
r.json().then((posts)=>setPosts(posts))
}
})
}, [])
And this is my how my route looks like
get '/posts/:id', to: "posts#show"
Lastly, this is where my backend fetches blog posts that are related to the logged in user.
def show
posts = Post.find_by(id:params[:id])
render json: posts, include: :user
end
I know the fact that find_by method only fetches the first record that meets the condition.
I also tried using user.Post.all
to fetch the records. Any advices?
CodePudding user response:
Currently your request will return the Post
with the :id
of your currentUser
. I think that's not what you want... :)
I guess you want something like:
def show
posts = User.find(params[:id]).posts # Hint: find_by(id: id) == find(id)
...
end
CodePudding user response:
You are using the routes, the controller, and the request in a weird way.
Problems
I assume the controller you shared is the Posts Controller, that means you need the Index action, not the Show action. The Show action is used when you want to render a single Post.
You pass the currentUser.id
to the backend as posts/:id
. I'm afraid that's not right as the posts/:id
refers to a Post id not a User id. Apart from that, your Backend should be already aware of the User as it is logged in.
Your authorization gem should have a way to access the current User. For example, the devise gem exposes has a method called current_user
to all the controllers.
Solution
That means your route should be get '/posts', to: "posts#index"
Your controller should be
def index
posts = current_user.posts # current_user or your way to access the user
render json: posts, include: :user
end
Your React front-end should be
export default function Profile({currentUser}){
const [posts, setPosts] = useState([])
useEffect(() => {
fetch(`/posts`)
.then((r) =>{
if(r.ok){
r.json().then((posts)=>setPosts(posts))
}
})
}, [])