I have two models Author and Post. I want an author to be able to create posts and have an association between those two models. I normally do this by nesting author and posts so the url would look like author/:id/posts. In this case, I use params[id] to find the Author and everything works. However, this time, I want the posts to appear on their on own like /posts/name-of-post and the same with authors; they would appear as author/name-of-author. To create the slugs I'm using the friendly_id gem. I have the slug working on the author controller. However, I can't find a way to create a post and create the association.
Please help me create the post and associate it to the author.
Author model
class Author < ActiveRecord::Base
has_many :posts
validates :name, :slug, presence: true
extend FriendlyId
friendly_id :name, use: :slugged
end
Post model
class Post < ActiveRecord::Base
belongs_to :author
end
Author Controller
def new
@author = Author.new
respond_with(@author)
end
private
def set_author
@author = Author.friendly.find(params[:id])
end
def author_params
params.require(:author).permit(:name, :slug, :bio)
end
Post Controller
def new
@post = Post.new
respond_with(@post)
end
def create
@post = Post.new(post_params)
@post.save
respond_with(@post)
end
private
def set_post
@post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :body, :slug, :author_id)
end
Post _form (slim)
= form_for @post do |f|
- if @post.errors.any?
#error_explanation
h2 = "#{pluralize(@post.errors.count, "error")} prohibited this post from being saved:"
ul
- @post.errors.full_messages.each do |message|
li = message
.field
= f.label :title
= f.text_field :title
.field
= f.label :body
= f.text_area :body
.field
= f.label :slug
= f.text_field :slug
.field
= f.label :author
= f.text_field :author
.actions = f.submit 'Save'
The associations work fine when I try them on the console. My problem is that I can't get the id of the author to de automatically populated on the new post form view and create the relationship when I save the new post.
You'll want to create the post the same way you were creating posts before. The fact that you want to be able to see a post individually, unconnected to an author, doesn't need to change how you created them.
So, for example, for the url /author_slug/posts/new
, your controller actions might look like:
# posts_controller.rb
def new
@author = Author.friendly_find(params[:author_id])
@post = @author.posts.build
end
Then, on your authorless route of posts/post-slug-from-friendly-id
, you'd just need to get the author from the post. Something like:
# routes.rb
get 'posts/:post_slug', to: posts#anonymous_show
# posts_controller.rb
def anonymous_show
@post = Post.friendly_find(params[:post_slug])
@author = @post.author
end