2

I have two tables that I put relationship with blog and post_categories. Below is the schema:

  create_table "blogs", force: :cascade do |t|
    t.string "title"
    t.text "body"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "slug"
    t.integer "status", default: 0
    t.bigint "post_category_id"
    t.index ["post_category_id"], name: "index_blogs_on_post_category_id"
    t.index ["slug"], name: "index_blogs_on_slug", unique: true
  end

  create_table "post_categories", force: :cascade do |t|
    t.string "name"
    t.text "description"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

Now what I am trying to do is to display the category name instead of category id on my blog index.html.erb file. I did the following but did not work:

<tbody>
    <% @blogs.each do |blog| %>
      <tr>
        <td><%= blog.title %></td>
        <td><%= blog.body %></td>
        <% PostCategory.all.each do |c| %>
          <% if c.id == blog.post_category %>
          <td><%= c.name %>
          <% end %>
        <td><%= link_to 'Show', blog %></td>
        <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
        <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>

Note: I also tried accessing it directly via <td><%= blog.post_category.name %></td>but did not work still.

Any idea how can I display the category name instead of category id associated?

1
  • If I used this <td><%= blog.post_category %></td> it gives me something like this: #<PostCategory:0x007fafd058f070> Commented Jan 2, 2019 at 6:17

2 Answers 2

1

As per you schema provided, it is noted that PostCategory object has many Blog objects

model changes,

class PostCategory < ApplicationRecord
  has_many :blogs
end

class Blog < ApplicationRecord
  belongs_to :post_category
end

view changes,

<tbody>
  <% @blogs.each do |blog| %>
    <tr>
      <td><%= blog.title %></td>
      <td><%= blog.body %></td>
      <td><%= blog.post_category.name rescue 'No post category present for this blog' %></td>
      <td><%= link_to 'Show', blog %></td>
      <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
      <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?'} %></td>
    </tr>
  <% end %>
Sign up to request clarification or add additional context in comments.

11 Comments

RAY Tried this already but got undefined method `name' for nil:NilClass
updated answer, it is your data problem as association and schema is proper but you do not have data as per association. use of try method can handle issue
@MarcSolva for blog.post_category_id, there must be id present in table post_categories
It works but is it safe to just let "try" method handle the work? is this a good practice? Also can explain the association issue more?
RAY - do i need to add a migration id for the post_categories table to solve this issue?
|
0

model changes,

class PostCategory < ApplicationRecord
  has_many :blogs
end

class Blog < ApplicationRecord
  belongs_to :post_category
end

view changes,

<tbody>
  <% @blogs.each do |blog| %>
    <tr>
      <td><%= blog.title %></td>
      <td><%= blog.body %></td>
      <td><%= blog.post_category.try(:name) %></td>
      <td><%= link_to 'Show', blog %></td>
      <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
      <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?'} %></td>
    </tr>
  <% end %>

10 Comments

PG::UndefinedColumn: ERROR: column post_categories.blog_id does not exist LINE 1: ... "post_categories".* FROM "post_categories" WHERE "post_cate...
First reset your database and start creating
Why you are calling post_categories.blog_id
Downvoted! blog belongs_to :post_category as blogs table have foregin key post_category_id
belongs_to :post_category as blogs place this on my blog model but I got this: compile error # GET /blogs.json def index @blogs = Blog.all end def post_category_0
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.