moctopus
moctopus

Reputation: 183

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.

Upvotes: 2

Views: 1318

Answers (3)

ryanb
ryanb

Reputation: 16287

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" %>

Upvotes: 1

kriysna
kriysna

Reputation: 6168

@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>

Upvotes: 0

Dylan Markow
Dylan Markow

Reputation: 124429

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.

Upvotes: 0

Related Questions