I am working on a Rails 4 application and recently got into a strange issue. I am looking for your help here. Kindly advise.
A small gist snippet has been created to understand the issue undefined method committed?
Just to summarize everything:
# app/models
class User < ActiveRecord::Base
has_many :responses, dependent: :destroy
end
class Response < ActiveRecord::Base
has_one :report
has_many :points
belongs_to :user
end
class Report < ActiveRecord::Base
belongs_to :response
end
class Point < ActiveRecord::Base
belongs_to :response
end
# config/routes.rb
resources :users do
resources :responses do
resources :action_plans
end
end
# app/controllers/action_plans_controller.rb
class ActionPlansController < ApplicationController
before_filter :response
def new
#report = #response.build_report
5.times do
#response.points.build
end
end
private
def response
#response = current_user.responses.find(params[:id])
end
end
Whenever, I am trying to hit:
http://localhost:3000/users/:user_id/responses/:id/action_plans/new
I get error that says: undefined method `committed?' for Response Object. What I am doing wrong here?
By defining a method called response in your controller you're overriding an internal getter used by Rails. To solve the problem, just use a different name for your before action. The common way of naming the action is to use set_<entity name> so set_response it is.
There is a Response class namespaced inside ActionDispatch (ActionDispatch::Response) and it is used throughout Rails. Can it be the case that you're actually hitting the response object instead of your model? Maybe use pry-rails to debug it from inside?
Related
Trying to build a friends feature on top of a Solidus framework, but the .friends method does not work. It does in rails console, however.
SpreeUsers Controller (current_spree_user.friends causes error):
class SpreeUsersController < ApplicationController
def my_friends
#friendships = current_spree_user.friends
end
def search
#spree_users = SpreeUser.search(params[:search_param])
render json: #spree_users
end
end
Friendship Model:
class Friendship < ActiveRecord::Base
belongs_to :spree_user
belongs_to :friend, :class_name => 'SpreeUser'
end
SpreeUser Model:
class SpreeUser < ActiveRecord::Base
has_many :friendships
has_many :friends, through: :friendships
end
Error:
undefined method `friends' for # Did you mean? friendly_id?
https://i.stack.imgur.com/u4F8K.png
Console Input/Output:
https://i.stack.imgur.com/YuVjb.png
I believe I know what is happening here.
You have declared a model SpreeUser with a friends relationship. This is why in your console it works. You are correctly calling the friends method on the class SpreeUser.
The error you are receiving is for the class Spree::User (Note the different class names). I am assuming you are using spree_auth_devise which provides that class.
You will need to properly add your logic from SpreeUser to Spree::User. I believe Spree/Solidus recommends doing so using decorators.
EG
Spree::User.class_eval do
has_many :friendships
has_many :friends, through: :friendships
end
Above not tested and a best guess taken from this SO answer
You could also test my theory by running Spree::User.first.friends in your console. You should receive a similar error to the browser.
I'm working with three tables as follows:
article.rb
class Article < ActiveRecord::Base
has_many :comments
has_many :comentarios, :through => :comments
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :article
has_many :comentarios
end
and comentario.rb
class Comentario < ActiveRecord::Base
belongs_to :article
end
Everything works fine until I attempt to add a 'comentario' and returns this error
ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection in ComentariosController#create
Cannot modify association 'Article#comentarios' because the source reflection class 'Comentario' is associated to 'Comment' via :has_many.
This is the code I use to create a new 'comentario'
comentarios_controller.rb
class ComentariosController < ApplicationController
def new
#comentario = Comentario.new
end
def create
#article = Article.find(params[:article_id])
#comentario = #article.comentarios.create(comentario_params)
redirect_to article_path(#article)
end
private
def comentario_params
params.require(:comentario).permit(:comentador, :comentario)
end
end
The output returns an error in the line where I create #comentario from calling #article but I can't see why since Ruby documentation says that once I associate comentario to article using :through, I can simply call something like #article.comentario.
Any idea of what is causing this error?
or do you have any suggestion on how to achieve this association in any other way?
Ok. The issue is that Rails is confused about which article to use here.
Your Comment model belongs_to :article but also your Commentario belongs_to :article... so if you use #article.commentarios - it's confused as to whether the article refers to the article of the comment or the article of the commentario.
You will probably need to update your form to be more explicit about what you're referring to. A form for the commentario should actually include fields for the comment it creates.
Somebody else had the same problem here. You may wish to look at the solution here: "Cannot modify association because the source reflection class is associated via :has_many"
I have a Rails 3.2 app which contains the following models:
class Costproject < ActiveRecord::Base
has_one :costquestion, :dependent => :destroy
class Costquestion < ActiveRecord::Base
belongs_to :costproject
When I create a costproject, I want one related costquestion created.
In the cosproject model, I tried:
after_save :create_costquestion
protected
def create_costquestion
self.costquestion.build
end
But, self seems to be nil - why is that?
undefined method `build' for nil:NilClass
Thanks for the help!
As other points out the reason, why the error, I wouldn't re-iterate it. And here is a solution you can use :
def create_costquestion
self.build_costquestion
self.save!
end
Check the helper methods comes with this associations from Rails.
Note: your method create_costquestion is what Rails already created for you by its magic. So, better give it a new name which shouldn't overwrite the out of the box method.
Edit: A little change to save the child while saving parent.
class Costproject < ActiveRecord::Base
has_one :costquestion, :dependent => :destroy, autosave: true
costquestion is nil this point. You're pointing to a relationship that doesn't yet exist. If you changed this to be something like this you should be ok:
def create_costquestion
costquestion = Costquestion.build #does this save?
self.costquestion = costquestion
self.save
end
I have namespaced model Equipment::Feature and namespaced controller in my admin part Admin::Equipment::FeaturesController. Model is generic and is used as from within :admin namespace and for public website. I've set up the routing for :admin and :equipment namespaces
namespace :admin do
namespace :equipment do
resources :features
end
end
Which gives me following routes:
admin_equipment_features GET /admin/equipment/features(.:format) admin/equipment/features#index
POST /admin/equipment/features(.:format) admin/equipment/features#create
new_admin_equipment_feature GET /admin/equipment/features/new(.:format) admin/equipment/features#new
edit_admin_equipment_feature GET /admin/equipment/features/:id/edit(.:format) admin/equipment/features#edit
admin_equipment_feature GET /admin/equipment/features/:id(.:format) admin/equipment/features#show
PUT /admin/equipment/features/:id(.:format) admin/equipment/features#update
DELETE /admin/equipment/features/:id(.:format) admin/equipment/features#destroy
Pretty standard stuff. But when I address /admin/equipment/features it throws uninitialized constant Admin::Equipment::FeaturesController::Equipment exception
#index action in my Admin::Equipment::FeaturesController looks like
def index
#features = Equipment::Feature.all
end
It did seem to work, until I declared Admin::Equipment namespace. Before it was like Admin::EquipmentFeaturesController
I guess this is some sort of namespace collision, but I don't get it - where does it come from?
Thanks in advance!
UPDATE Feature model (uses STI pattern)
class Equipment::Feature < ActiveRecord::Base
attr_accessible :category_id, :name_en, :name_ru, :type
belongs_to :category, :class_name => 'Equipment::Category'
has_many :item_features, :class_name => 'Equipment::ItemFeature'
has_many :items, :through => :item_features
translates :name
end
class FeatureBoolean < Equipment::Feature
end
class FeatureNumeric < Equipment::Feature
end
class FeatureString < Equipment::Feature
end
class FeatureRange < Equipment::Feature
end
UPDATE2
Fixing #index action as per answer below resolved the issue. New code:
def index
#features = ::Equipment::Feature.all
end
I think it's now looking for Feature in Admin::Equipment, rather than in ::Equipment
Try specifying that there is no namespace, i.e.
def index
#features = ::Equipment::Feature.all
end
Please create folder like this app/controllers/admin/equipment/features.rb
And then edit your controller name to Admin::Equipment::FeaturesController
class Admin::Equipment::FeaturesController < ActiveRecord::Base
end
rails 3 newbie, using Devise for auth...
I want to create the following models:
class Instance < ActiveRecord::Base
has_many :users
has_many :notes
end
class User < ActiveRecord::Base
belongs_to :instance
end
class Note < ActiveRecord::Base
belongs_to :instance
end
To create a new note in the notes_controller.rb
def create
#note = instance.notes.build(params[:note].merge(:instance_id => current_user.instance_id))
end
But I'm getting the following ERROR: "undefined local variable or method `instance' for #"
Ideas?
You haven't assigned anything to "instance" yet, so there's nothing to reference. If you know the instance record already exists in the database, you could do something like:
#instance = current_user.instance
#note = Note.create(:instace_id => #instance.id)
If not, you'd need to check and create it first if necessary, using the same kind of syntax.