Need some help with JSON API structure.
Say we have the following:
class User < ApplicationRecord
has_many :posts
end
class Post < ApplicationRecord
has_many :comments
belongs_to :user
end
class Comment < ApplicationRecord
belongs_to :post
has_many :talkbacks
end
class Talkbacks < ApplicationRecord
belongs_to :comment
end
Now, the api points should be something like the following:
/posts
/posts/:id
/posts/:id/comments
/comments
/comments/:id
/comments/:id/talkbacks
/talkbacks
/talkbacks/:id
If we'd like to show a post, making sure posts belong to the current user is easy assuming we have a token:
# /posts/:id
current_user.posts.find_by_id!(params_id)
However, if we want to show a specific talkback, it is more difficult to make sure the talkback belongs to the user:
# /talkbacks/:id
What would be the best way to make sure the user can access to that talkback?
You should flesh out your relationships with a has_one, through
relation. Then, it's easy to perform the query. You don't need to add a user_id to the task field (and shouldn't as the post should handle that association). The has_one
relation allows you do effectively have a belongs_to
relation through another model and removes the need to have a join table.
class User < ApplicationRecord
has_many :posts
has_many :comments, through: :posts
has_many :talkbacks, through: :comments
end
class Post < ApplicationRecord
belongs_to :user
has_many :comments
has_many :tasks, through: :comments
end
class Comment < ApplicationRecord
belongs_to :post
has_one :user, through: :post
has_many :talkbacks
end
class Talkbacks < ApplicationRecord
belongs_to :comment
has_one :user, through: :comment
end
Then you can do, in your controller,
current_user.talkbacks.find(params[:id])
As an aside in your post...
current_user.posts.find_by_id!(params_id)
posts.find_by_id!()
is equivalent to posts.find()
so you don't need to do the by_id!
part. By default, Rails will raise an exception if it cannot find a record with the find
method, same as using the bang on a find_by_id
method.