Kingsley Simon
Kingsley Simon

Reputation: 2210

rails pass variable from model to another controller

I have a rails project and i want to pass a variable from my User model to another controller.

How do i do that? I know it is not the best way to do it but I cant think of any other way to solve my issue.

I am using Devise for my login and I want to display a link if the sign_in fails due to user being locked.

In my User model, i have this method

def after_database_authentication
  update_attributes!(password_changed_at: self.last_activity_at)
  user_locked = self.is_locked
end

I want to add this variable user_locked in my Post controller.

so in my Post controller method new, i want to use it here

def new 
  ap user_locked
end

Felt the only way i could this was using sessions but cannot assign sessions variable in rails model.

Any other options will be appreciated. Thanks

Upvotes: 1

Views: 1302

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

I think you're getting confused with the MVC structure.

Your model is a class which is either populated with database data, or has pre-defined data in the form of class methods / variables.

Thus, when you ask....

i want to pass a variable from my User model to another controller

... the context is completely incorrect.


Model

If you want to pass a value through your model, you'll either store it in the database (so one of the model's attributes is populated with the value), or you'll store it as a value at the class level:

#app/models/user.rb
class User < ActiveRecord::Base
   def is_locked?
      true #-> User.new.is_locked? -> true
   end

   def self.is_locked?
      false #-> User.is_locked? -> false
   end
end

From what you've written, I would strongly recommend making is_locked a database attribute:

$ rails g migration AddIsLockedToUsers

# db/migrate/add_is_locked_to_users________.rb
class AddIsLockedToUsers < ActiveRecord::Migration
   def change
      add_column :users, :is_locked, :boolean, default: false
   end
end

$ rake db:migrate

This will set the is_locked? value as an attribute of your User model, which means that each time you call a User, you'll be able to check whether they are locked or not:

#app/controllers/posts_controller.rb
class PostsController < ApplicationController
   def new
      @user = User.find params[:user_id]
      redirect_to root_path if @user.is_locked?
   end
end

--

On top of this, you may wish to use an ActiveRecord::Observer or an after_update callback to update the locked status:

#app/models/user.rb
class User < ActiveRecord::Base
   after_update :set_locked, if: "password_changed_at.changed?"

   private

   def set_locked
      self.is_locked = true
   end
end

Upvotes: 0

Tetiana Chupryna
Tetiana Chupryna

Reputation: 1074

As you use Devise, the helper method current_user is available for you. So why don't you use such solution?

class User
  def locked?
    is_locked
  end
end

UserController
  def new
    current_user.locked?
  end
end

Upvotes: 1

Related Questions