2

I am a rookie in Rails. I am using Rails 4 and I could not find how they do this or what it is called.

I got this idea from devise where you can use devise and implement such thing in your application.html.erb file:

<% if user_signed_in? %>
      Logged in as <strong><%= current_user.email %></strong>.

Where user is the devise model. However when I try to search for user_signed_in or current_user variable, I cannot find it at all!

So essentially what I want to do is link this user model (which is used for devise) with another model that I created called profile. These models are linked by their ids, and if user has not created a profile, then simply ask user to create his/her profile. To do that, I've written this to application.html.erb:

<% if user_signed_in? && (current_profile.id != current_user.id)? %>
    <%= link_to 'You have not created your profile! Please create your profile first.', update_profile_index_path, :class => 'navbar-link'  %>
<% else %>
    <%= yield %>
<% end %>

Which does not work as expected because I have not defined current_profile. The error that I am getting is:

undefined local variable or method `current_profile' for #<#<Class:0x000000044d6c60>:0x00000005d64110>

My question is, how do I create a variable named current_profile that would contain the current profile, like current_user that devise does?

Sarp Kaya
  • 3,686
  • 21
  • 64
  • 103
  • Why don't you simply use current_user.profile ? – Rafal Aug 27 '14 at 13:21
  • current_user is a devise model. It does not have a profile? – Sarp Kaya Aug 27 '14 at 13:21
  • if you define has_one profile on the user model, then current_user.profile will work – Rafal Aug 27 '14 at 13:22
  • I already did that for both and it doesn't work. I am getting undefined method `profile?' for # error if I do that – Sarp Kaya Aug 27 '14 at 13:22
  • then you need to define `def profile?; return self.profile; end` on your User model – Rafal Aug 27 '14 at 13:23
  • or call it without the question mark. And you need user_id:integer to be defined on the profile model for the association to work – Rafal Aug 27 '14 at 13:24
  • for defining that, when I used that then I get a SQL error: SQLite3::SQLException: no such column: profiles.user_id: SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = ? LIMIT 1 Which is expected because, user_id in profiles is not set yet (that's why it should be created) – Sarp Kaya Aug 27 '14 at 13:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60088/discussion-between-rafal-and-sarp-kaya). – Rafal Aug 27 '14 at 13:28

2 Answers2

3

The usual setup for this is to add a Profile model with a user_id:integer field.

Define an assocition on the User model

has_one :profile

Then you can access it directly using

current_user.profile
Rafal
  • 2,576
  • 2
  • 18
  • 13
3

You can do the following:

class User
  has_one :profile
  # ...

class Profile
  belongs_to :user
  # ...

module ApplicationHelper # app/helpers/application_helper.rb
  def current_profile
    @current_profile ||= current_user.try(:profile)
    @current_profile
  end
  # ...

# view
<% if user_signed_in? && current_profile.blank? %>
  <%= link_to 'You have not created your profile! Please create your profile first.', update_profile_index_path, :class => 'navbar-link'  %>
<% else %>
  <%= yield %>
<% end %>
MrYoshiji
  • 54,334
  • 13
  • 124
  • 117
  • I have has_one in Profile as well because I want to strict that one profile has only one user? – Sarp Kaya Aug 27 '14 at 13:34
  • @SarpKaya see [Choosing Between `belongs_to` and `has_one`](http://guides.rubyonrails.org/association_basics.html#choosing-between-belongs-to-and-has-one) – Stefan Aug 27 '14 at 13:38
  • It worked like a charm! And this kind of thing was what I was wanting at the first place! – Sarp Kaya Aug 27 '14 at 13:39
  • @Stefan I want to use primary key of both, I don't really need a separate field, therefore both of them are has_one. – Sarp Kaya Aug 27 '14 at 13:40
  • 1
    @SarpKaya where do you store the foreign key - is there a `profile_id` field in your `users` table or a `user_id` field in your `profiles` table? – Stefan Aug 27 '14 at 13:49
  • I don't have any extra field in `users` table. I have `user_id` field in `profiles` table. I don't have any extra id field for the `profiles` table. So I simply want to create one-on-one id matching. Ie, I have 10 users, `user.id(10)` is a quick user and creates a profile before them, in that case the `user_id` field in the `profiles` would be 10. By doing that I simply save one entire id field in `profiles` and in `users` table. – Sarp Kaya Aug 27 '14 at 13:53
  • 1
    The model holding the `belongs_to :something` part is the model that holds the column `something_id`. In your case `User has_one :profile` and `Profile belongs_to :user` – MrYoshiji Aug 27 '14 at 13:58
  • For some reason this does not work in controllers. It works in views but when I am at the controller it simply cannot find. However the `current_user` is available in both controller and viewer. When I look at the content of self, I cannot find current_profile? – Sarp Kaya Aug 31 '14 at 03:23
  • See this answer @SarpKaya http://stackoverflow.com/questions/5130150/rails-how-to-use-a-helper-inside-a-controller – MrYoshiji Sep 02 '14 at 13:14
  • @MrYoshiji that does not include anything for Rails 4 – Sarp Kaya Sep 02 '14 at 13:48
  • add `include ApplicationHelper` in `ApplicationController` to make the helper method `current_profile` available for all controllers – MrYoshiji Sep 02 '14 at 16:55