Find account name

I have an accounts table
ACCOUNTS
id
company_name

and a users table
USERS
id
username
password
account_id

I want a page where I display the company_name for the user. So far, I
managed to get the user_id from the session…
<%= session[:user_id] %>

Now, I guess I can use the user_id, to find it’s account_id, and then
match the account_id and get the company_name.

I don’t know, maybe I’m overcomplicating things. I just managed to get
the user_id and I’m now stuck.

On 13 October 2010 21:05, Leonel . [email protected] wrote:

account_id

I want a page where I display the company_name for the user. So far, I
managed to get the user_id from the session…
<%= session[:user_id] %>

Now, I guess I can use the user_id, to find it’s account_id, and then
match the account_id and get the company_name.

If you have a user in current_user for example then the company is
current_user.company, so the name is current_user.company.name. Such
is the magic of Rails. Watch out for the cas when the user does not
have a company, in which current_user.company will be nil. Check out
the rails guide on ActiveRecord relationships to see how this all
works.

Colin

Simplified it even more…

CONTROLLER
@current_user = User.find(session[:user_id])

TEMPLATE

<%= @current_user.account.name %>

On 13 October 2010 21:42, Leonel . [email protected] wrote:

Simplified it even moreeeee for the designer…

CONTROLLER
@company_name = User.find(session[:user_id]).account.name

OK, but did you take heed of my warning in my first reply? Can you
guarantee that a user will always have a company (even in unusual
circumstances)? Add into your automated tests one where the user does
not have a company and see what happens. (Hint, find returns nil if
it cannot find what you are asking for).

Another point, it might be worth providing a method somewhere called
current_user (possibly in application_controller) that does the find,
then you will not need to keep typing the find everywhere you want
current_user.

Colin

If you have a user in current_user for example then the company is
current_user.company, so the name is current_user.company.name. Such
is the magic of Rails. Watch out for the cas when the user does not
have a company, in which current_user.company will be nil. Check out
the rails guide on ActiveRecord relationships to see how this all
works.

Thanks! This is what I did…

CONTROLLER
current_user_id = session[:user_id]
@current_user = User.find(current_user_id)

TEMPLATE

<%= @current_user.account.name %>

Seems soo simple but it’s not to us newbies.

Simplified it even moreeeee for the designer…

CONTROLLER
@company_name = User.find(session[:user_id]).account.name

TEMPLATE

<%= @company_name %>

OK, but did you take heed of my warning in my first reply? Can you
guarantee that a user will always have a company (even in unusual
circumstances)? Add into your automated tests one where the user does
not have a company and see what happens. (Hint, find returns nil if
it cannot find what you are asking for).

Every time an user is created, the account_id is recorded on its row
too. But sure it’s good to have a safety net.

Another point, it might be worth providing a method somewhere called
current_user (possibly in application_controller) that does the find,
then you will not need to keep typing the find everywhere you want
current_user.

Aight! DRYer and DRYer

Another point, it might be worth providing a method somewhere called
current_user (possibly in application_controller) that does the find,
then you will not need to keep typing the find everywhere you want
current_user.

I’m trying to do exactly that, but the app doesn’t seem to find the
session if placed on the application controller.

ACCOUNTS_CONTROLLER (works fine)
User.find(session[:user_id]).account.name

APPLICATION_CONTROLLER (error!)
User.find(session[:user_id]).account.name

ERROR
Couldn’t find User without an ID

Found something very weird, the log trace reads…

DEPRECATION WARNING: Disabling sessions for a single controller has been
deprecated. Sessions are now lazy loaded. So if you don’t access them,
consider them off. You can still modify the session cookie options with
request.session_options. (called from
[…]/app/controllers/application_controller.rb:6)

Ok, so I made this change: I used find_by_id instead of just find.

APPLICATION CONTROLLER
@company_id = User.find_by_id(session[:user_id]).account.id

ERROR
Routing Error
undefined method `account’ for nil:NilClass

I’m not good at routing, but will read about it right now. If you got a
suggestion is very much welcomed.

On 14 October 2010 16:32, Leonel . [email protected] wrote:

APPLICATION_CONTROLLER (error!)
User.find(session[:user_id]).account.name

ERROR
Couldn’t find User without an ID

Can you show us the code around the error and how you are calling it?

Colin

2010/10/14 Leonel . [email protected]

suggestion is very much welcomed.

You might be searching for a user before a session is established, as
such
the session[:user_id] is nil. You may need to revise the position of
this
statement: @company_id = User.find_by_id(session[:user_id]).account.id
in
your application_controller. Remember that often the application
controller
the first to load even when you are just open your application. You may
need
to add a condition. Something like:
@company_id = User.find_by_id(session[:user_id]).account.id if
session[:user_id]

A General Note:

Personally, I would not recommend writing
User.find_by_id(session[:user_id]).account.id although Rails natually
allows
for this short cut. For testing sake (or whether you call it bug hunt),
I
would find the user first and search for the user’s account. In that way
I
will be able to test for the avaliabilty of the user and the
availability of
the account separately. I should say, despite that “every time an user
is
created, the account_id is recorded on its row too”, bugs are are bugs,
they
always bug. Anything can happen midway. So consider revising that
statement.
This is a personal preference, based on my experience. It is subject to
comments and criticisms.

Happy coding.


Edmond
Software Developer | Baobab Health Trust (http://www.baobabhealth.org/)
|
Malawi

Cell: +265 999 465 137 | +265 881 234 717

*“Leading the Improvement of Health through Information and
Communication
Technology in the Developing World” The *Creed of *Baobab Health
*

Colin L. wrote in post #950191:

On 14 October 2010 16:32, Leonel . [email protected] wrote:

APPLICATION_CONTROLLER (error!)
User.find(session[:user_id]).account.name

ERROR
Couldn’t find User without an ID

Can you show us the code around the error and how you are calling it?

mmm… I think I need some tweaking on the routes file. This is all the
code in my application controller

class ApplicationController < ActionController::Base
before_filter :authorize

protect_from_forgery

@company_name = User.find(session[:user_id]).account.name

protected

def authorize
  unless User.find_by_id(session[:user_id])
    redirect_to login_url, :notice => "Please log in"
  end
end

end

On 14 October 2010 17:27, Leonel . [email protected] wrote:

protect_from_forgery

@user_id = User.find_by_id(session[:user_id])
@account_id = @user_id.account.id

Doing it like that means that it will get executed when the controller
loads, which in production will be only once. You need to put it in a
method of application_controller then call it from your code when you
want to know the result.

Are you using authlogic? If so I am sure the examples of how to use
it include how to do a current_user method.

Colin

For testing sake (or whether you call it bug hunt),
I would find the user first and search for the user’s account. In that way
I will be able to test for the avaliabilty of the user and the
availability of the account separately.

Thanks, ok, so I did this…

APPLICATION CONTROLLER
class ApplicationController < ActionController::Base
before_filter :authorize

protect_from_forgery

@user_id = User.find_by_id(session[:user_id])
@account_id = @user_id.account.id

protected

def authorize
  unless User.find_by_id(session[:user_id])
    redirect_to login_url, :notice => "Please log in"
  end
end

end

ERROR
Routing Error
undefined method `account’ for nil:NilClass

Like the error reads, I think I need to do something on the routes file.
I’m not sure what 'cause I’m a newbie but I’m searching for the answer.

Colin L. wrote in post #950219:

On 14 October 2010 17:27, Leonel . [email protected] wrote:

protect_from_forgery

@user_id = User.find_by_id(session[:user_id])
@account_id = @user_id.account.id

Doing it like that means that it will get executed when the controller
loads, which in production will be only once. You need to put it in a
method of application_controller then call it from your code when you
want to know the result.

Are you using authlogic? If so I am sure the examples of how to use
it include how to do a current_user method.

So you mean doing something like this in the application controller?
def current_user
User.find_by_id(session[:user_id])
end

I use the user id, the account id, the account name and the account id
in several parts of the application. Everytime I need to access the data
I have to add something like this on each controller method…

class AccountsController < ApplicationController

GET /accounts

GET /accounts.xml

def index
@accounts = Account.all

@company_id = User.find(session[:user_id]).account.id
@company_name = User.find(session[:user_id]).account.name
@company_address_one = 

User.find(session[:user_id]).account.address_one
@company_address_two =
User.find(session[:user_id]).account.address_two
@company_city = User.find(session[:user_id]).account.city
@company_state = User.find(session[:user_id]).account.state
@company_zip = User.find(session[:user_id]).account.zip
@company_web_address =
User.find(session[:user_id]).account.web_address
@company_phone_number_office =
User.find(session[:user_id]).account.phone_number_office
@company_phone_number_fax =
User.find(session[:user_id]).account.phone_number_fax

How can I make the company name available to all views with something
like this… @company_name

So you mean doing something like this in the application controller?
def current_user
User.find_by_id(session[:user_id])
end
That’s usually sensible.

Since current_user is defined in
ApplicationController, and since all your other controllers inherit from
ApplicationController, all you need in your controller is

@current_user = current_user

and then do @current_user.account.whatever in the view.

How can I make the company name available to all views with something
like this… @company_name

I tried it, and it does work. But how can I make it work on the
APPLICATION CONTROLLER instead of on an individual controller. Several
views need the account_id, so I would have to repeat myself in several
controllers writing
@company_name = company_name

For example with this code in the application controller…

def company_id
@company_id = User.find_by_id(session[:user_id]).account.id
end
@company_id = company_id

I get this error…
Routing Error
undefined local variable or method `company_id’ for
ApplicationController:Class

Still same error…

APPLICATION CONTROLLER
@company_id = company_id
def company_id
output_id = User.find_by_id(session[:user_id]).account.id
end

ERROR
Routing Error
undefined local variable or method `company_id’ for
ApplicationController:Class

Why would it say the method is undefined, if it ISSSS defined? and why
would it have something to do with the routes if it’s just a simple
method and a simple variable?

Leonel . wrote in post #950292:
[…]

So you mean doing something like this in the application controller?
def current_user
User.find_by_id(session[:user_id])
end

That’s usually sensible.

I use the user id, the account id, the account name and the account id
in several parts of the application. Everytime I need to access the data
I have to add something like this on each controller method…

class AccountsController < ApplicationController

GET /accounts

GET /accounts.xml

def index
@accounts = Account.all

@company_id = User.find(session[:user_id]).account.id
@company_name = User.find(session[:user_id]).account.name
@company_address_one =

User.find(session[:user_id]).account.address_one
@company_address_two =
User.find(session[:user_id]).account.address_two
@company_city = User.find(session[:user_id]).account.city
@company_state = User.find(session[:user_id]).account.state
@company_zip = User.find(session[:user_id]).account.zip
@company_web_address =
User.find(session[:user_id]).account.web_address
@company_phone_number_office =
User.find(session[:user_id]).account.phone_number_office
@company_phone_number_fax =
User.find(session[:user_id]).account.phone_number_fax

No, you certainly don’t. Since current_user is defined in
ApplicationController, and since all your other controllers inherit from
ApplicationController, all you need in your controller is

@current_user = current_user

and then do @current_user.account.whatever in the view.

How can I make the company name available to all views with something
like this… @company_name

Use a before_filter or the technique I just described.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

I tried to simplify to find the root of the problem, but this doesn’t
work either!

APPLICATION CONTROLLER
@company_id = 1;

VIEW
<%= @company_id %> returns nothing