"undefined method" for a rails model - ruby

I am using Devise with rails and i want to add a method "getAllComments", so i write this :
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :city, :newsletter_register, :birthday, :postal_code,
:address_complement, :address, :lastname, :firstname, :civility
has_many :hotels_comments
class << self # Class methods
def getAllComments
true
end
end
end
And in my controller :
def dashboard
#user = current_user
#comments = #user.getAllComments();
end
And when i go to my url, i got
undefined method `getAllComments' for #<User:0x00000008759718>
What i am doing wrong?
Thank you

Because getAllComments is a class method and you are attempting to access it as an instance method.
You either need to access it as:
User.getAllComments
or redefine it as an instance method:
class User < ActiveRecord::Base
#...
def getAllComments
true
end
end
def dashboard
#user = current_user
#comments = #user.getAllComments
end

As I can see, you make getAllComments as class method through addition it to eigenclass. And you try to call this method from instance.

Content of class << self means class method. It could be shortened as def self.getAllComments
You should call it User.getAllComments and not #user.getAllComments

The getAllComments() method that you wrote is a class method
So the correct way to call the methods is
#comments = User.getAllComments
But if you really want to scope the getAllComments to the current user, I recommend you write an instance method
class User < ActiveRecord::Base
..
def getAllComments
// comments implementation
end
So that way you can access the getAllComments method like so:
#user = current_user
#comments = #user.getAllComments

Related

Using devise current_user

I have a user and an address for example and the relation is as follows:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :address
end
class Address< ActiveRecord::Base
belongs_to :user
end
Now when I create an address object, I want to be able to pass through the current_user id and save it to the address model, so in my controller I have
before_filter :authenticate_user!
def new
#address= current_user.address.new
end
def create
#address= current_user.address.new(address_params)
if #address.save
redirect_to root_path, notice: 'Address Successfully Created'
else
render action: 'new'
end
end
private
def address_params
params.require(:address).permit(:id, :user_id, :add_1, :add_2, :add_3)
end
I can't access the new action at the moment, as the error I am getting is
undefined method `new' for nil:NilClass
What am I missing?
I think you should do it like this:
def new
#address = current_user.build_address
end
And same in create action
More info here

Devise Override RegistrationController issue with resource.active_for_authentication?

I want to override this controller, in this moment the create method, I already made a little change on it
class RegistrationsController < Devise::RegistrationsController
def create
unless session[:invitation_token].blank?
super
else
redirect_to new_user_session_path and return
end
end
end
after following the flow of sign up the resource is created in the database like the super class define it
def create
build_resource
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_with resource
end
end
but in some way there is a problem with the method active_for_authetication?
Is throwing false and I can't figure out why I checked all the gem and it says that the method is overridden by other modules the normal definition is
def active_for_authentication?
true
end
but I don't use any of the modules that override it so for some reason it seems like devise its not being able to succeed that validation but the user is stored in the database and I'm signed in after registration.
This is my configuration for register a user.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :username
end
This is my Initializer for devise
Devise.setup do |config|
config.mailer_sender = "please-change-me-at-config-initializers-devise#example.com"
require 'devise/orm/active_record'
config.case_insensitive_keys = [ :email ]
config.strip_whitespace_keys = [ :email ]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 10
config.password_length = 6..15
config.reset_password_within = 6.hours
config.sign_out_via = :delete
end

How to access ActiveModel attributes from a method call on the class?

I need to reference user#role to define an association in a module. I've tried with a block as shown below, but that doesn't work. How does Rails implement behavior like this?
class User < ActiveRecord::Base
include Profile
has_profile { |user| { class_name: "#{user.role}::Profile" }}
end
module Profile
extend ActiveSupport::Concern
module ClassMethods
def has_profile(&block)
role = ### How to access #role ? ###
class_eval do
has_one :profile, class_name: "#{role}::Profile"
end
...
You might need to do something like this. I didn't tested and I'm just supposing you can do this kind of stuff
class User < ActiveRecord::Base
include Profile
has_profile { |user| user.role }
end
module Profile
extend ActiveSupport::Concern
included do
after_initialize :_init_profile
end
def _init_profile
role = #_role_block.call(self)
# Here we do class eval on singleton so we dont change base class
# I'm not sure if this works as it is but should be close enought
class << self; self; end.class_eval do
has_one :profile, class_name: "#{role}::Profile"
end
end
module ClassMethods
def has_profile(&block)
#_role_block = block
...
This works:
module Models
module Profile
extend ActiveSupport::Concern
included do
after_initialize :_init_profile
end
module ClassMethods
def has_profile(&block)
#profile_association_block = block
end
end
def _init_profile
block = self.class.instance_variable_get :#profile_association_block
self.class.has_one :profile, block.call(self)
end

ActiveModel::MassAssignmentSecurity::Error in ApiUsersController#create

I am not able to create new api_user. Everytime I try to create it I get
Can't mass-assign protected attributes: utf8, authenticity_token, api_user, commit, action, controller
here's my model api_user.rb
class ApiUser < ActiveRecord::Base
attr_accessible :api_key, :count, :email, :name, :organization
end
controller api_users_controller.rb
class ApiUsersController < ApplicationController
#skip_before_filter :verify_authenticity_token
def new
#api_user = ApiUser.new
end
def create
#api_user=ApiUser.create(params)
render :text=>"#{#api_user.id}"
end
def destroy
#api_user=ApiUser.find(params[:id])
#api_user.destroy
render :text=>"Deleted successfully"
end
end
I am using Ruby 1.9.2 and Rails 3.2.3
In order to create the ApiUser, you should use only the correct params:
#api_user=ApiUser.create(params[:api_user])
not all the paramshash

Rails 3 - Devise: users route

I am using devise with CanCan. I am using my user model.
My user index page is localhost:3000/users (It is enabled just for :administrator role).
The problem is that CanCan (or Devise) is not checking for authorization on this route. All other routes (i.e. localhost:3000/tasks) are being checked. i.e. If I logout of the system and type the users index page it displays its content. If I type the tasks route it redirects me to the login screen (correct behaviour).
I think that this is happening because of Devise's routes.
My simplified User model is:
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :role_ids, :role, :email, :password, :password_confirmation, :remember_me
def role?(role_check)
self.roles.each do |role|
return true if (role.name.eql? role_check.to_s.humanize )
end
return false
end
def role=(role_id)
self.roles.clear
self.roles << Role.find(role_id)
end
def role
self.roles.first unless self.roles.length == 0
end
end
My Routes are the following:
devise_for :users
resources :users
devise_for :users, :controllers => { :registrations => "users/registrations" }
My ability.rb is the following (I havenĀ“t defined yet, it is allowing all):
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.role? :administrator
can :manage, :all
elsif user.role? :department_header
can :manage, :all
elsif user.role? :staff
can :manage, :all
end
end
end
How can I fix this?
Thanks!
My problem was on the following line:
load_and_authorize_resource :only => [:show,:new,:destroy,:edit,:update]
I have to include :index

Resources