Xavier
Xavier

Reputation: 4017

One to One relation between tables in Rails

Just started my first project in ROR and i'm facing a problem with build a relation between table. As a noob i search a lot around the web, try plenty of stuff but can't figure out how to get this working. Here's my issue: I built a User table for the login function - made with devise, now i want to build another table UserMeta to carry all the profile info of my users.

Here is the code of what i did:

app/models/user.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  attr_accessible :email, :password, :password_confirmation, :remember_me
  attr_accessible :email, :encrypted_password

  has_one :user_meta
end

*app/models/user_meta.rb*

class UserMeta < ActiveRecord::Base
  attr_accessible :admin, :birthday, :company, :first_name, :job, :last_name, :phone, :rfid, :statut, :website, :user_id

  belongs_to :users
end

class User
  has_one :user_meta
end

*app/controllers/user_controllers.rb*

  def new
    @user = User.new
    @meta = UserMeta.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @user }
    end
  end

app/views/users/new.html.erb

<%= form_for(@meta) do |f| %>
  <div class="field">
    <%= f.label :phone %><br />
    <%= f.text_field :phone %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

It returns :

undefined method `meta_index_path' for #<#<Class:0x000001016f3f18>:0x00000100e9f6f0>

I know there is one or many mistake, what the best way to do this ? Some help will be appreciated :)

Upvotes: 0

Views: 815

Answers (2)

Rahul Tapali
Rahul Tapali

Reputation: 10147

You can change to like this:

app/models/user.rb

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  attr_accessible :email, :password, :password_confirmation, :remember_me, :encrypted_password

  has_one :user_meta
  accepts_nested_attributes_for :user_meta
end

app/models/user_meta.rb

class UserMeta < ActiveRecord::Base
  attr_accessible :admin, :birthday, :company, :first_name, :job, :last_name, :phone, :rfid, :statut, :website, :user_id

  belongs_to :user
end

app/controllers/user_controllers.rb

def new
  @user = User.new
  @user.build_meta_user

   respond_to do |format|
     format.html
     format.json { render json: @user }
   end
end

app/views/users/new.html.erb

<%= form_for @user, :url => {:action => 'create'} do |f| %>
  <!-- User related fields -->
  <%= f.fields_for :user_meta do |meta_f| %>
    <div class="field">
      <%= meta_f.label :phone %><br />
      <%= meta_f.text_field :phone %>
    </div>
  <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Upvotes: 1

Dimitri
Dimitri

Reputation: 161

  • In Rails it's best to name your classes the same as your filenames. So app/models/user_meta.rb should be class UserMeta < ActiveRecord::Base.

  • There's no need to re-open the User-class in app/models/user_meta.rb. He'll know about app/models/user.rb already.

  • Change your belongs_to :users to belongs_to :user

  • In app/models/user.rb you can drop the 2nd attr_accessible :email.

Upvotes: 1

Related Questions