Adding my comments to the index view...Ruby on Rails - ruby-on-rails

Ok...I am new to rails so this may be a stupid question but need help. I just watched and implemented Ryan Bates screencaset about setting up a blog. You can see it here http://media.rubyonrails.org/video/rails_blog_2.mov. Here is the skinny:
Two tables: Posts and Comments. Everything works great including the addition of comments via AJAX. The default development of this blog gives you the index.html.erb view where you can view all the posts
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
The comments are only viewed via the show.html.erb page and is displayed via this code in that file:
<%= render :partial => #post %>
<p>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Destroy', #post, :method => :delete, :confirm => "Are You Sure" %> |
<%= link_to 'See All Posts', posts_path %>
</p>
<h2>Comments</h2>
<div id="comments">
<%= render :partial => #post.comments %>
</div>
<% remote_form_for [#post, Comment.new] do |f| %>
<p>
<%= f.label :body, "New Comment" %><br/>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Add Comment"%></p>
<% end %>
What I am trying to do is to get similair representation of the comments functionality to exist in the index.html.erb view (which I will hide with javascript). Which currently just looks like this:
<h1>Listing posts</h1>
<%= render :partial => #posts %>
<%= link_to 'New post', new_post_path %>
My initial thought was just to put this exact same code that is in the show.html.erb file in the index.html.erb file but that doesn't work. I have tried a bunch of things here but I am not familiar enough with Rails (or coding for that matter) yet to do this in a timely manner. I get two main errors. Either that I passed a nil.comments error or an undefined object/method (can't remember).
My question is what do I need to included in the post_controller, the comments_controller and the index.html.erb file to accomplish this. To be complete I have included the code in each below.
POSTS_CONTROLLER
class PostsController < ApplicationController
before_filter :authenticate, :except => [:index, :show]
# GET /posts
# GET /posts.xml
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/new
# GET /posts/new.xml
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to(#post) }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to(#post) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
private
def authenticate
authenticate_or_request_with_http_basic do |name, password|
name == "admin" && password == "secret"
end
end
end
COMMENTS_CONTROLLER
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create!(params[:comment])
respond_to do |format|
format.html { redirect_to #post}
format.js
end
end
end
INDEX.HTML.ERB
<h1>Listing posts</h1>
<%= render :partial => #posts %>
<%= link_to 'New post', new_post_path %>

Here's one simple solution. Step 1, edit your index action to include all the comments belonging to each post.
def index
#posts = Post.all(:include => :comments)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
Step 2, edit your index view to display each post, followed by its comments:
<h1>Listing posts</h1>
<% #posts.each do |post| %>
<%= render :partial => post %>
<%= render :partial => post.comments %>
<% end %>
<%= link_to 'New post', new_post_path %>
Edit: I'm not 100% sure of the best way to include the comment creation form also. What I'd try first is this (in index.html.erb):
Try changing your index view to:
<h1>Listing posts</h1>
<% #posts.each do |post| %>
<%= render :partial => post %>
<%= render :partial => post.comments %>
<% remote_form_for [post, Comment.new] do |f| %>
<p>
<%= f.label :body, "New Comment" %><br/>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Add Comment"%></p>
<% end %>
<% end %>
<%= link_to 'New post', new_post_path %>
This should render the "New comment" form for a given post under the comments for that post, but I'm not sure (without actually trying it out) whether the form submission AJAX will successfully update and refresh the index page.

Related

NoMethodError in Jobs#show

I've been stuck on this all day. When I try to show the details of a job, create a job, or edit a current job in my ruby on rails project I get a NoMethodError in Jobs#show on the second last line explaining there is a problem with the link to the edit page.
Jobs/show.html
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #job.name %>
</p>
<p>
<strong>Employer:</strong>
<%= #job.employer %>
</p>
<p>
<strong>Sector:</strong>
<%= #job.sector_id %>
</p>
<p>
<strong>Experience req:</strong>
<%= #job.experience_req %>
</p>
<p>
<strong>Job info:</strong>
<%= #job.job_info %>
</p>
<h2>Star comment: </h2>
<%=form_for([#job, Request.new]) do |f| %>
</h3></br>
<%= f.text_area:content, :rows => 4, :cols=> 40%>
<div class = "actions">
<%=f.submit "Make a request for the job"%>
</div>
<% end %>
<%if #job.requests.empty? %>
<h3> You are the first to Request</h3>
<% else %>
<h2> Who else had made a request for this job:</h2>
<% #job.requests.reverse.each do |request| %>
<p><%= request.content %>
Posted <%=time_ago_in_words(request.created_at)%> ago by
<%=request.candidate.can_name%></p>
<% end %>
<% end %>
<%= link_to 'Edit', edit_jobs_path(#job) %> | **This line highlights an error**
<%= link_to 'Back', jobs_path %>
Jobs/edit.html
<h1>Editing job</h1>
<%= render 'form' %>
<%= link_to 'Show', #job %> |
<%= link_to 'Back', jobs_path %>
Routes
Rails.application.routes.draw do
# get 'sessions/new'
# get 'sessions/create'
#get 'sessions/destroy'
controller :sessions do
get 'login' =>:new
post 'login' =>:create
get 'logout' =>:destroy
delete 'logout' =>:destroy
end
#get 'pages/home'
#get 'pages/about'
resources :candidates
resources :requests
resources :employers
resources :jobs
resources :sectors
# The priority is based upon order of creation: first created -> highest
# priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'pages#home'
#root :to=>'pages#home
#'welcome#index'
resources :jobs do
resources :requests
end
end
Jobs_Controller
class JobsController < ApplicationController
before_action :set_job, only: [:show, :edit, :update, :destroy]
# GET /jobs
# GET /jobs.json
def index
#jobs = Job.all
end
# GET /jobs/1
# GET /jobs/1.json
def show
end
# GET /jobs/new
def new
#job = Job.new
end
# GET /jobs/1/edit
def edit
end
# POST /jobs
# POST /jobs.json
def create
#job = Job.new(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.'
}
format.json { render :show, status: :created, location: #job }
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity
}
end
end
end
# PATCH/PUT /jobs/1
# PATCH/PUT /jobs/1.json
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully updated.'
}
format.json { render :show, status: :ok, location: #job }
else
format.html { render :edit }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
# DELETE /jobs/1
# DELETE /jobs/1.json
def destroy
#job.destroy
respond_to do |format|
format.html { redirect_to jobs_url, notice: 'Job was successfully
destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_job
#job = Job.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white
#list through.
def job_params
params.require(:job).permit(:name, :employer, :sector_id,
:experience_req,:job_info)
end
end
Update
Ursus informed me I had to change <%= link_to 'Show', #job %> to<%= link_to 'Show', job_path(#job) %> in Jobs/edit.html. I did this, however when I try to create a new job or edit a current job I still get the same error but the new job is still created?
This
<%= link_to 'Show', #job %>
should be
<%= link_to 'Show', job_path(#job) %>

Rails 4.0 ActiveRecord::RecordNotFound

I am trying to learn Rails and am making my first app and am running into this error:
ActiveRecord::RecordNotFound in PartsController#show
Couldn't find Part with id=new_ic
with the highlighted source:
def set_part
#part = Part.find(params[:id])
end
I am brand new to rails and i can't figure out what is wrong and I can't find any help online either. The app is a part management system for electronic components. The form gets filled out and the data is saved to the database for future reference/updating. Could someone please help?
Source code time:
parts/_ic_form.html.erb
<h1>Add An IC</h1>
<%= simple_form_for #parts do |f| %>
<%= f.input :component_type, :as => :hidden, :input_html => { :value => "IC"} %>
<%= f.input :ic_model, label: 'IC Model' %>
<%= f.input :ic_manufacturer, label: 'IC Manufacturer' %>
<%= f.input :ic_pinCount, label: 'IC Pin-Count' %>
<%= f.input :ic_mountType, collection: ["Through Hole", "Surface Mount"], label: 'IC Mount Type' %>
<%= f.input :ic_package, label: 'IC Package' %>
<%= f.input :ic_quantityOnHand, label: 'Quantity On Hand' %>
<%= f.input :ic_quantityOnOrder, label: 'Quantity On Order' %>
<%= f.button :submit %>
<% end %>
parts/new_ic.html.erb
<%= render 'ic_form' %>
parts/new.html.erb
<h1>New part</h1>
<%= link_to 'IC', 'new_ic' %>
<%= link_to 'Back', parts_path %>
parts_controller.rb
class PartsController < ApplicationController
before_action :set_part, only: [:show, :edit, :update, :destroy]
before_filter :initialize_parts
def initialize_parts
#parts = Part.new
end
# GET /parts
# GET /parts.json
def index
#parts = Part.all
end
# GET /parts/1
# GET /parts/1.json
def show
end
# GET /parts/new
def new
#part = Part.new
end
# GET /parts/1/edit
def edit
end
# POST /parts
# POST /parts.json
def create
#part = Part.new(part_params)
respond_to do |format|
if #part.save
format.html { redirect_to #part, notice: 'Part was successfully created.' }
format.json { render action: 'show', status: :created, location: #part }
else
format.html { render action: 'new' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /parts/1
# PATCH/PUT /parts/1.json
def update
respond_to do |format|
if #part.update(part_params)
format.html { redirect_to #part, notice: 'Part was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# DELETE /parts/1
# DELETE /parts/1.json
def destroy
#part.destroy
respond_to do |format|
format.html { redirect_to parts_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_part
#part = Part.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def part_params
params[:part]
end
end
routes.rb Pretty sure i screwed this one up too
Pms::Application.routes.draw do
resources :parts
resources :parts
root to: "parts#new_ic"
end
rake routes Output:
Prefix Verb URI Pattern Controller#Action
parts GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
new_part GET /parts/new(.:format) parts#new
edit_part GET /parts/:id/edit(.:format) parts#edit
part GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
GET /parts/new(.:format) parts#new
GET /parts/:id/edit(.:format) parts#edit
GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
root GET / parts#new_ic
One problem is in this line:
<%= link_to 'IC', 'new_ic' %>
link_to should look like this:
link_to "Profile", profile_path(#profile)
#Profile is the name
#profile_path(#profile) is the link
Try this instead:
#parts/new.html.erb
<%= link_to 'IC', root_path %>
in your routes, root GET / parts#new_ic is linking to your new_ic action. I'd disagree with the way you access it (via root) - but it will work if you want to access the new_ic action. Why is this your root route, though?

Rails posts scaffold not parsing html

I'm trying to learn rails, and am using my blog as an excuse to do so.
Right now, I'm playing around with the posts scaffold. I get the MVC and the idea behind it, so I was about to recreate it, when I ran accross the following error.
If I enter content like
text
text
text
in the 'content' tag of posts form, It displays all the text as one block.
text text text
I thought I could try doing something like
<p>text</p>
<p>text</p>
<p>text</p>
but, it shows
<p>text</p><p>text</p><p>text</p>
What I'd like Rails to do is to actually parse the html in content. What would I do to get that to happen?
Here's the New Form Partial, which I used to submit the content
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here's the Posts Controller as a whole
class PostsController < ApplicationController
# GET /posts
# GET /posts.json
def index
#posts = Post.paginate(page: params[:page])
respond_to do |format|
format.html # index.html.erb
format.json { render json: #posts }
end
end
# GET /posts/1
# GET /posts/1.json
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #post }
end
end
# GET /posts/new
# GET /posts/new.json
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.json
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
end
To prevent XSS attacks Rails escapes html by default. If you don't want your html escaped you have to use .html_safe on the string you don't want escaped. In show.html.erb:
<%= #post.content.html_safe %>
Or a better way would be not to enter <p>'s in your content field and use simple_format to do the formatting into paragraphs, like this:
<%= simple_format(#post.content) %>
Of course you could also use a combination of both. E.g. when you have omitted paragraph tags, but do have links in your content:
<%= simple_format(#post.content.html_safe) %>
Note that you can safely use .html_safe on content you entered yourself, but don't use it on content that is entered by third parties (like comments) for that would open up your site to XSS attacks.
Mischa's answer led me down a rabbit hole of searching, and I also found this gem -- https://github.com/spohlenz/tinymce-rails
It adds TinyMCE, a wysiwig editor to a textarea

Limiting Comments on Posts Index in Rails App

I am new to rails and trying to limit the number of comments displayed on my Posts Index Page to 2.
Below is my posts_controller:
class PostsController < ApplicationController
before_filter :authorize, :except => [:index, :show]
# GET /posts
# GET /posts.xml
def index
#posts = Post.all(:include => :comments, :order => "created_at DESC")
#comments = Comment.find(:all, :order => "created_at DESC", :limit => 1)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/new
# GET /posts/new.xml
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to(#post, :notice => 'Post was successfully created.') }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to(#post, :notice => 'Post was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
end
Below is my Post model
class Post < ActiveRecord::Base
has_attached_file :photo, :styles
=> { :medium => "600x600>", :thumb => "100x100>" },
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => "/:attachment/:id/:style/:filename"
has_many :comments
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
end
Below is my posts index view
<table>
<tr>
<th>BoxScore</th>
<th>Content</th>
</tr>
</table>
<% #posts.each do |post| %>
<%= image_tag post.photo.url(:medium), :class =>"floatleft" %>
<p>
<%= post.content %>
</p>
<div class="comments center">
<h3>Comments:</h3>
<%= render :partial => post.comments.reverse %>
<div class="links">
<% if admin? %>
<%= link_to "New Post", new_post_path %>
<%= link_to 'Edit', edit_post_path(post) %>
<%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %>
<% end %>
<%= link_to 'Comment on the Game', post %>
</div>
</div>
<% end %>
</div>
Comments Partial Below
<% div_for comment do %>
<p>
<strong>Posted <%= time_ago_in_words(comment.created_at) %> ago
</strong>
by
<br/>
<%= h(comment.commenter) %>
<br/>
<%= h(comment.body) %>
<br/>
<%= link_to 'More Comments', comment.post %>
</p>
<% end %>
I am not getting an error message, I just don't know how to limit the amount of comments we are rendering on Posts index page. Thanks
You can't specify conditions on eager loaded associations, unfortunately. Likewise, you can't limit the number of rows returned based on a condition (to my knowledge, though there are a lot of things I don't know about SQL functions).
So you're stuck with either:
Load all of the comments for the posts you're displaying in a query, and limit the number shown in your application.
Load only 2 comments for each of the posts you're displaying individually.
The optimal solution depends on your use case. If you're expecting to show only 5 posts and have thousands of comments on each, option 1 might not be very performant and option 2 might be a good solution. If you are expecting to show more posts per page and have only a handful of comments on any one (the more likely scenario), the first option is going to be your best bet.
Option 1
# controller
#posts = Post.limit(20).all
#comments = Comment.find(#posts.collect &:id).group_by &:post_id
# view
<% #comments[#post.id].first(2).each do |comment| %>
...
<% end %>
Option 2
# controller
#posts = Post.limit(5).all
# view
<% post.comments.limit(2).each do |comment| %>

Accessing a referenced field using mongoid/mongodb/rails

If I have a model...
class Post
include Mongoid::Document
field :link
field :title
field :synopsis
field :added_on, :type => Date
validates_presence_of :link
embeds_many :replies
references_one :topic
end
and
class Topic
include Mongoid::Document
field :category
referenced_in :post
end
What would I need to code in index.html.erb to access data in topic or to add a topic to post.
I tried post.topic but I get an undefined method error.
Thank you very much.
Edit:
Here is the index.html code
<div id="post">
<% #posts.each do |post| %>
<div class="title_container">
<%= link_to post.title, post.link %> || <%= link_to 'Edit', edit_post_path(post) %> || <%= post.topic %>
</div>
<% end %>
<br />
<h2>Topics<h2>
<% for topic in #post.topics %>
<h3><%= topic.category %></h3>
<% end %>
</div>
here is the posts_controller
class PostsController < ApplicationController
# GET /posts
# GET /posts.xml
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/new
# GET /posts/new.xml
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to(#post, :notice => 'Post was successfully created.') }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to(#post, :notice => 'Post was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
end
Edit:
I am also adding the relevant _form.html.erb code.
<div class="field">
<%= f.label :topic_id %>
<%= f.collection_select :topic, Post.topic, :id, :category, :prompt => "Select a Topic" %>
</div>
Edit:
Updated to 2.0.0.rc.7 still can't get it.
Tried the key method in the railscast video (http://railscasts.com/episodes/238-mongoid) just for fun. I get a "BSON::InvalidObjectId in PostsController#update" error.
I'm guessing a topic has many posts? If you want a referenced association you need to change it to this.
class Post
#...
referenced_in :topic
end
class Topic
#...
references_many :posts
end
Then try changing your collection_select line to this:
<%= f.collection_select :topic_id, Topic.all, :id, :category, :prompt => "Select a Topic" %>
Your post.rb file has a references_one :topic, but in your index view, you're doing for topic in #post.topics, implying that a post can have many topics. Either you need to change your model to say references_many :topics or change your view to work with only having one topic per post.
#user593120
Did you tried this in your index.html.erb
<div id="post">
<% #posts.each do |post| %>
<div class="title_container">
<%= link_to post.title, post.link %> || <%= link_to 'Edit', edit_post_path(post) %> || <%= post.topic %>
</div>
<% end %>
<br />
<h2>Topics<h2>
<% #posts.each do |post| %>
<h3><%= post.topic.category if post.topic %></h3>
<% end %>
</div>

Resources