undefined method `model_name' for #<Class:0x007f043631a380> - ruby-on-rails

I ran through similar problems here but nothing seems to match my problem. I got the error undefined method model_name for #<Class:0x007f043631a380>. It points to line #1 of my /app/views/classes/new.html.erb file:
<%= form_for #class do | f | %>
<div class = “form-group”>
<%= f.label :name %>
<%= f.text_field :name, class: ‘form-control’ %>
My app/controllers/classes_controller.rb:
class ClassesController < ApplicationController
def new
#class = Class.new
end
end
My app/models/class.rb:
class Class < ActiveRecord::Base
validates :name, presence: true
validates :teacher, presence: true
validates :day, presence: true
validates :start_time, presence: true
validates :duration, presence: true, numericality: { only_integer: true }
end
I am very new to RoR and don't really know where to look for a problem. Could you give me direction?

Your code seem good. It is probably because class is a reserved word in rails : https://reservedwords.herokuapp.com/
Try to name your models and controllers something that would not look like some ruby code.
EDIT: What Roman says is correct. Your controller is always plural. Try renaming your controller first as ClassesController.

The Class.new line is probably unintentionally referencing the Ruby class Class. You could try namespacing your Class, for instance:
module MyModels
class Class < ActiveRecord::Base
end
end
and then using MyModels::Class would probably work, but I try to avoid naming things Class. I'm not sure, since you have 2 classes at the root named the same if there's any other way to specify which you're referencing, and if you specifically require and re-define Class, I'm not even sure what types of problems would ensue, but I'm sure it wouldn't be my ideal afternoon.
One thing that I often see done, when the name is needed, is to name custom Class classes and class variables as Klass and klass. Most coders (that I know, at least), wouldn't even blink twice seeing something like that named with a K.

Make sure your controller and views name is plural. Try ClassesController and views/classes/new.html.erb.

You can not use a reserved keyword in rails and ruby as your model name.
Your class name should be like SchoolClass or something like that.

Related

Is it possible to prevent empty action text entries

I have a very simple action text model and form
class Course < ApplicationRecord
validates :title, presence: true
has_rich_text :content
end
<%= form_with model: #course do |f| %>
<%= f.text_field :title %>
<%= f.rich_text_area :content %>
<% end %>
It's all working great but since the content field is optional is it possible to create a course model without creating action_text_rich_texts entries that are empty/blank? Even if the user only enters the title without any content it's currently creating them and there's a lot of unnecessary and empty action_text_rich_texts rows in the database
The way I handled this in my application is with a before_save callback that removes the ActionText::RichText database record if the body is blank.
This avoids polluting the controller and works on both create and update actions. The body attribute of the action_text attribute is still accessible even without a corresponding database record, because ActionText will instantiate a new object if the record cannot be found (which allows you to test for blank? in either scenario).
Try this:
class Course < ApplicationRecord
validates :title, presence: true
has_rich_text :content
before_save :clean_up_content
private
def clean_up_content
self.content.destroy if self.content.body.blank?
end
end
I'm not sure about anything built into Actiontext for this, but I would imagine you could handle this at the controller level.
The first thing I would try is to see if not setting anything to content prevents Rails from creating an associated record:
class CourseController
def create
# remove course_params[:content] if it's blank
course_values = course_params[:content].blank? ? course_params.except(:content) : course_params
Course.create(course_values)
...
end
end
Extending Eric Powell's approach:
# app/models/concerns/do_not_save_blank_rich_text.rb
module DoNotSaveBlankRichText
extend ActiveSupport::Concern
included do
before_validation :do_not_save_blank_rich_text
end
private
def do_not_save_blank_rich_text
rich_text_attributes = self.class.reflections.values.select do |reflection|
reflection.options[:class_name] == "ActionText::RichText"
end.map(&:name)
rich_text_attributes.each do |rich_text_attribute|
if self.public_send(rich_text_attribute) && self.public_send(rich_text_attribute).body.blank?
self.public_send(rich_text_attribute).mark_for_destruction
end
end
end
end

How to understand the colon operator usage in a Ruby class

I am learning both Ruby (2.3.x) & Rails (4.x). I was going through the Ruby On Rails Tutorial and I encountered this syntax and am having trouble reading it:
class User < ApplicationRecord
validates :name, presence: true
validates :email, presence: true
end
Does this class define validates as a method which takes in a :name symbol and a hash presence:true? The same thing applies to line 3.
Or it is something entirely else? All attempts to run it resulted in:
uninitialized constant ApplicationRecord.
I looked at the source(maybe?) but am still not clear.
This is a special DSL introduced by ApplicationRecord. What you are actually doing is calling those methods inside class during declaration. It adds those validations to your class, so whenever you try to save a record it will fail if you don't have email or name
Try this
user = User.new
user.save
user.valid? # false
And try to do the same without validates.
If it will make things more clear for you, you can try write this class like this
class User < ApplicationRecord
validates(:name, presence: true)
validates(:email, presence: true)
end
validates is implemented as a class method in ActiveModel::Validations.
The ActiveModel::Validations module is included in ApplicationRecord, therefore you are able to call that method when your User class is loaded.
validates accepted an array and treats the last element of that array as an options hash (if the last element is an hash).
validates is a pre-defined helper that Active Record offers to use in Rails to make the validation work easier, this way you can with some single lines of code manage several validations of several attributes.
As it's a helper within Rails it's also a method defined in the ActiveModel module, in the core of the framework, see: active_model/validations.rb
The most common is the presence attribute which you're facing the trouble with, that specifies that the attribute used isn't empty, doing it in the Ruby way through the blank? method to check if the value passed isn't blank nor nil.

Simple way in ruby to ignore error if object doesn't exist

I have two objects: Wine, Brand
Brand has_many :wines
Wine belongs_to :brand
How can I simplify the following code:
<%= #wine.brand.name if #wine.brand %>
I realize it's already very simple, but I have some different complexities in my code that make this cumbersome. What I'd like to do is something along the lines of:
<%= &#wine.brand.name %>
Where it basically ignores the error. In PHP you can do this, I just can't find a corollary for ruby.
You can use try method:
<%= #wine.brand.try(:name) %>
I'd rather do this as follows:
class Wine
def brand_name
brand.present? ? brand.name : ''
end
end
This keeps your view slightly cleaner:
<%= #wine.brand_name %>
You can use delegate:
class Wine < ActiveRecord::Base
belongs_to :brand
delegate :name, to: :brand, prefix: true, allow_nil: true
end
This creates a Wine#brand_name method, returning either the brand's name or nil if brand does not exist.

Do I need to update an attribute in rails? (and how?)

I generated scaffolding for a class: ExpenseReport
One of the attributes was type - which I created a selct for, where two options where possible: Major and Regular.
When submitting the form to create a report, I was pulling this error:
Invalid single-table inheritance type: Regular is not a subclass of ExpenseReport
My assumption was - "Okay, let's just not have an attribute called type, it looks like that may be causing problems." So I created a migration, renaming type to "report type" and raked (see migration and proof of rake below)
Migration
class UpdaeColumnName < ActiveRecord::Migration
def change
rename_column :expense_reports, :type, :report_type
end
end
Proof of Rake
Drews-MacBook-Pro:depot drewwyatt$ rails generate migration UpdaeColumnName
invoke active_record
create db/migrate/20130820215925_updae_column_name.rb
Drews-MacBook-Pro:depot drewwyatt$ rake db:migrate
== UpdaeColumnName: migrating ================================================
-- rename_column(:expense_reports, :type, :report_type)
-> 0.0021s
== UpdaeColumnName: migrated (0.0021s) =======================================
Now, however, it never ever saves my input, and fires validation with every submit - telling me "Report type is not included in the list", is there another attribute name I need to update or something?
Relevant _form.html.erb
<div class="field">
<%= f.label :report_type %><br>
<%= f.select :report_type, ExpenseReport::TYPES,
prompt: "select one" %>
</div>
Model
class ExpenseReport < ActiveRecord::Base
validates :place_of_purchase, :items, :reason, :estimated_cost,
:requestor_name, presence: true
TYPES = [ 'Major', 'Regular' ]
validates :report_type, inclusion: TYPES
SITES = [ '001 (Lubbock)', '002 (Odessa)', '003 (Midland)', '004 (Lubbock)' ]
validates :site, inclusion: SITES
end
The attribute "type" is for single table inheritance, more about can be found here: http://railscasts.com/episodes/394-sti-and-polymorphic-associations or here: http://rails-bestpractices.com/posts/45-use-sti-and-polymorphic-model-for-multiple-uploads
If you stay with your new report_type, you should change your scaffold stuff. Are you on rails 4? If yes, change your private expense_report_params method in your expense_reports_controller.rb
Should be something like that:
def expense_report_params
params.require(:expense_report).permit(:place_of_purchase, :items, :reason, :estimated_cost, :requestor_name, :other_attributes, :type)
end
Change it to:
def expense_report_params
params.require(:expense_report).permit(:place_of_purchase, :items, :reason, :estimated_cost, :requestor_name, :other_attributes, :report_type)
end
In rails 4 you always have to permit your params..otherwise it would not work. If you permit a params "type" which does not exist, you´ll get an error..

uninitialized constant ActionView::CompiledTemplates::Category

using this tutorial
http://railscasts.com/episodes/57-create-model-through-text-field
need to make it work in my app, was on rails 3.0.7 and it worked fine, updated it to 3.1.3 and I got this error now
uninitialized constant ActionView::CompiledTemplates::Category
I would look for answers more time but now I am really short on time. I have looked into most part of google results related to this problem and no good. Need help please.
form
<%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
or create one:
<%= f.text_field :new_category_name %>
model
class Tvstation < ActiveRecord::Base
belongs_to :category
attr_accessor :new_category_name
before_save :create_category_from_name
def create_category_from_name
create_category(:name => new_category_name) unless new_category_name.blank?
end
end
ok, just for others if they will get into this stupid things as I did, don't forget to have the category.rb in the app/models..
class Category < ActiveRecord::Base
...
end
For me, i got the similar problem in the views. My Category model is available inside namespace example
Module Financial
class Category
end
end
When i call simply Category.get_method. It was giving same error. so that i modified into Financial::Category that solved my problem.
I was using a PORO and it wasn't loading, giving me this error. It was because I had changed the class name without changing the file name.
How the others suggested I had a similar problem solved be fix of wrong model name.

Resources