Search code examples
ruby-on-railsrubypostgresqlruby-on-rails-4wice-grid

Trying to implement a grid view with a one-to-many association


Image has a one-to-many association with Category:

# Category model:
has_many :images
# Image model:
has_one :category
# Images migration file:
t.references :category, index: true, foreign_key: true

I'm trying to implement a grid view using the wice_grid gem. This works but one line is failing. The following works in the index view:

g.column name: 'Category', attribute: 'category_id', auto_reload: true, html: {id: 'grid-cells'} do |image|
  image.category_id
end

But this displays the number/id of the category, while I want it to display its name. If I try image.category instead of image.category_id there's an error:

PG::UndefinedColumn: ERROR:  column categories.image_id does not exist
LINE 1: SELECT  "categories".* FROM "categories" WHERE "categories"."image_id...

How can I have it display the category name instead of the id of the category?

Controller method:

def index
  @images_grid = initialize_grid(Image,
  # include: :category  # Do I need this? Tried it with and without
  per_page: 40)
end

Update: After correcting the association and using in the view the code below, it works. Except for the filter function for this specific column. If I enter text to filter on, it reloads the table, but without applying the filter (all records are still displayed).

g.column name: 'Category', attribute: 'category_id', auto_reload: true, html: {id: 'grid-cells'} do |image|
  image.category.category unless image.category.nil?
end

Solution

  • In the image model you should have belongs_to :category, not has_one. The association is the n-1, not 1-1.

    On the second part of your problem - filtering the items by category name, I believe you need to use a custom filter:

    g.column name: 'Category', attribute: 'images.category_id',
          custom_filter: Category.find(:all).map{|cat| [cat.id, cat.name]} do |image|
      image.category.name if image.category
    end