uninitialized constant ActionView::CompiledTemplates::Category - ruby-on-rails

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.

Related

Rails Issue with submitting form when adding nested form

A Rails newbie here. I believe I am rather confused as to how fields_for operates within a rails form. I have a has many through relationship formed with Projects, Organizations, and Affiliations in the middle. A Project can have many Organizations, and an Organization can have many Projects. Affiliations is in the middle with a :role attribute that is meant to be edited to show what role an Organization plays within a Project. I was able to get the functionality of adding many Organizations to a Project working just fine. I utilized chosen-rails to implement a neat UI to select multiple, search, etc. I can add and remove Organizations to a Project just fine with that. However, upon trying to implement some way to manipulate the role each Organization plays in a Project through altering the role attribute with a fields_for form, submissions of the original form break. I have tried many variations of the fields_form, including one from a guide here.
In project.rb:
def affiliations_attributes=(affiliations_attributes)
affiliations_attributes.each do |i, affiliation_attributes|
if affiliation_attributes[:role].length > 0
self.affiliations.build(affiliation_attributes)
end
end
end
In the project form:
<%= f.fields_for :affiliations do |affiliation_builder|%>
<%= affiliation_builder.label :role %>
<%= affiliation_builder.text_field :role %>
<% end %>
With this setup, on submission of the form, I receive an error stating that 'Affiliations organization must exist.' I don't understand why, since I'm not even editing the Affiliations or Organization here. Is there something I am missing?
Prior to this, I tried doing this for a fields_for form:
<%= f.fields_for :affiliations do |affiliation|%>
<%= affiliation.label :role, ("Role in Project") %>
<%= affiliation.text_field :role, autofocus: true, autocomplete: 'off', placeholder: 'e.g. Donor, Founder', class: 'form-control' %>
<% end %>
Projects Controller:
def project_params
params.require(:project).permit(:organization, {organization_ids: []},
:stream_name, :implementation_date, :narrative,
:length, :primary_contact,:number_of_structures, :structure_description,
:name, affiliations_attributes: [:id, :role], photos: [])
end
Now, surprisingly, this works when updating the role attribute in Affiliations. I can also add Organizations to the project with no issue, and add subsequent roles to the created Affiliation. However, the problem arises when I try to remove an Organization. Rails flashes an ActiveRecord::RecordNotFound in ProjectsController#update error stating "Couldn't find Affiliation with ID= for Project with ID=". I have no idea what is going on here and have been banging my head against the wall for a couple days now trying to fix this. The only thing I can think is somehow there's an ID matching issue, or some parameter not being properly passed. One thing I did notice when toying around with the project_params on the second method above and removing :id from affiliations_attributes is that I get flashed with the same error message about an 'Affiliations organization' being required. Perhaps there's some way to pass an organization ID with the affiliation_builder method? Any help or guidance would be greatly appreciated here. Thank you.
class Affiliation < ApplicationRecord
belongs_to :project
belongs_to :organization
end
class Organization < ApplicationRecord
has_many :affiliations
has_many :projects, through: :affiliations
end
class Project < ApplicationRecord
has_many :affiliations
has_many :organizations, through: :affiliations
accepts_nested_attributes_for :affiliations
def affiliations_attributes=(affiliations_attributes)
affiliations_attributes.each do |i, affiliation_attributes|
if affiliation_attributes[:role].length > 0
self.affiliations.build(affiliation_attributes)
end
end
end
end
I believe I have found a solution, though I am not sure if it is technically correct. I looked at the order of the attributes being pushed when Project was updated, and I noticed that organization_ids was being pushed in the Hash before affiliations_attributes. So I think it was trying to update something that just didn't exist, and was giving some misleading information (at least to me). I was able to fix this issue by forcing the affiliations_attributes to be pushed first in a separate update by itself, and then pushing the rest of the project attributes in the main update.
def project_organization_params
params.require(:project).permit(:id, {affiliations_attributes: [:id,
:role]})
end
And then update with:
#project = Project.find(params[:id])
#project.update(project_organization_params)
if #project.update(project_params)
...
Everything seems to be working just fine now.
Why |i, affiliation_attributes| ?
use |affiliation_attributes|

undefined method `model_name' for #<Class:0x007f043631a380>

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.

Rails Papertrail - display who Was Responsible for last change

I'm using Devise and Papertrail and would like to display which user made the most recent update (documentation link).
In controller:
def show
# #history = #person.versions.last
#last_change = #person.versions.last
#user_who_made_the_change = User.find #last_change.whodunnit.to_i
end
In show page
<%= #user_who_made_the_change %>
However I get the resulting error:
undefined method `whodunnit' for nil:NilClass
in app/controllers/people_controller.rb:15:in `show'
Any help would be much appreciated, thanks
I prefer to modify initializer to kept template clean.
config/initializers/paper_trail.rb
PaperTrail::Rails::Engine.eager_load!
module PaperTrail
class Version < ::ActiveRecord::Base
belongs_to :user, foreign_key: :whodunnit
end
end
history.html.erb
<% #versions.each do |version| %>
<%= version.user.email %>
<% end %>
There are many reasons for omit save version data (configuration, save without callbacks, save from console ...)
I think you must check if you have the information to show:
def show
#last_change = #person.versions.last
#user_who_made_the_change = (User.find(#last_change.whodunnit.to_i) if #last_change && #last_change.whodunnit) || nil
end
This must do the trick.
I've done a bit of googling this evening about this topic. I simply wanted to be able to write something like #post.versions.last.user and get the devise User record (ie the person whodunnit that version).
The way that worked for me was creating the paper_trail.rb initializer with
PaperTrail::Rails::Engine.eager_load!
module PaperTrail
class Version < ActiveRecord::Base
include PaperTrail::VersionConcern
belongs_to :user, foreign_key: :whodunnit
end
end
Some solutions gave me errors including json col not set or something and/or undefined methodtimestamp_sort_order'`.
This is just what worked for me.
Other options included creating this in your app/models which I liked the idea of but never tried cause this 'worked' and I have other code I want to write :)

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.

Elegant way to process collection_select in controller?

I am currently somewhat stuck figuring out an elegant solution to my following
problem:
Let's say I have the following classes:
class Event < ActiveRecord::Base
belongs_to :reg_template, :class_name => "EmailTemplate"
[...]
end
class EmailTemplate < ActiveRecord::Base
has_many :events
[...]
end
And a view that contains:
<%= f.collection_select(:reg_template_id, EmailTemplate.all, :id, :name) %>
What is the recommended way of processing this form field in an action
controller?
Having a 1:1 relationship between Event and EmailTemplate means that Rails
does not generate a reg_template_id and reg_template_id= method (as it would
do for a 1:n relationship), so attempts to read or assign this field will fail
with
unknown attribute: reg_template_id
when attempting to call
Event.update_attributes
Using
<%= f.collection_select(:reg_template, EmailTemplate.all, :id, :name) %>
instead also does not help much as it will fail with:
EmailTemplate(#70070455907700) expected, got String(#70070510199800)
I guess I must be missing something terribly obvious as I think is is rather
common to update a model instance with a reference to another object through a
collection_select.
If you have the column reg_template_id in the events table, then the following code should work:
<%= f.collection_select(:reg_template_id, EmailTemplate.all, :id, :name) %>

Resources