user3318660
user3318660

Reputation: 303

Rails Model Constants

I have Attachments and Category models so when a user uploads a file, they can select a category for that attachment. I want the categories to be static for now. Advice on how to create static Category model options? I have this right now but I get the following error: undefined method 'title' for Syllabus":String

Category Model

class Category < ActiveRecord::Base
  CATEGORY = ['Syllabus', 'Assignments', 'Handouts', 'Lectures', 'Other']
  has_many :attachments
end

Attachment new.html.erb

<%= simple_form_for([@group, @group.attachments.build]) do |f| %>

  <%= f.collection_select :category_id, Category::CATEGORY, :id, :title, { promt: "Choose a Category" } %>

<%= f.submit %>

<% end %>

Attachment Model

class Attachment < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
  belongs_to :category
end

Schema

 create_table "categories", force: :cascade do |t|
    t.string   "title"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

 create_table "attachments", force: :cascade do |t|
    t.string   "title"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.integer  "user_id"
    t.string   "name"
    t.integer  "group_id"
    t.integer  "category_id"
 end

Upvotes: 1

Views: 2650

Answers (2)

songyy
songyy

Reputation: 4573

Seems to me that the Category::CATEGORY should be a enum. There're at least two ways to achieve what you want:

  1. Single Table Inheritance: http://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html.
  2. enum: http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html

Kindly ask if you have any question with the guide.

Upvotes: 0

Andrew Hodgkinson
Andrew Hodgkinson

Reputation: 4789

You seem to want to have a fixed list of Categories and yet, presumably for future expansion, you want to refer to those via belongs_to and a category_id in the attachments model. You can't know in advance what category_id values your database engine, or anyone else's, might assign to Category objects were they to be created for real.

You're getting an error because collection_select is expecting the collection you give it to consist of real Category model instances which have methods like #title arising from the associated database table's attributes. Instead, you're trying to just give it an array of Strings.

Therefore, you should use seed data - Google for something like "rails 4 seed data" to get an idea of what to do. With seed data, you'll actually create real database instances of that Category model that get loaded up as part of your application's installation phase. The model just won't have any editing/management interface in early versions of your application, but real instances of it will be in the database nonetheless.

[Edit: I generally prefer the rake db:create db:migrate approach to bringing up applications, since db:schema:load may not always work especially if esoteric ID column constructions occurred in the migration files, which the schema.rb summary file may not have accurately recorded due to Rails bugs. Accordingly, I prefer to use the approach I described in a very old StackOverflow question's answer - Add Rows on Migrations - but YMMV, you may prefer things like seeds.rb instead.]

Upvotes: 1

Related Questions