Steven
Steven

Reputation: 502

Associatons between two models

Thank you for visiting. I'm still new to connecting models and have a question. I have two models currently:

create_table "users", force: true do |t|
 t.string   "first_name"
 t.string   "last_name"
 t.string   "email"
 t.string   "password_digest"
 t.string   "user_name"
 t.date     "birthdate"
 t.integer  "zip_code"
 t.string   "gender"
 t.datetime "created_at"
 t.datetime "updated_at"
 t.string   "avatar_file_name"
 t.string   "avatar_content_type"
 t.integer  "avatar_file_size"
 t.datetime "avatar_updated_at"
 t.string   "background_file_name"
 t.string   "background_content_type"
 t.integer  "background_file_size"
 t.datetime "background_updated_at"
 t.string   "slug"
end

create_table "user_avatars", force: true do |t|
 t.integer  "user_id"
 t.datetime "created_at"
 t.datetime "updated_at"
 t.string   "avatar_file_name"
 t.string   "avatar_content_type"
 t.integer  "avatar_file_size"
 t.datetime "avatar_updated_at"
end

As you can see the User model is getting really long and someone told me before it's better if I separate avatar to a separate model. My question is how will I be able to change a user profile information without having two separate Form_for fields? Since I would like for a user to be able to edit there user_name, first_name etc and also UserAvatar.avatar at the same time. Thank you for all the help and those who help me learn something new.

For more information please ask

User model

has_one :user_avatar

has_attached_file :avatar, :styles => {
 :medium => "200x200>",
 :small => "120x120#",
 :thumb => "75x75#",
 :default_url => "http://www.adtechnology.co.uk/images/UGM-default-user.png"
   }

validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/

UserAvatar model

belongs_to :user

has_attached_file :avatar, :styles => {
 :medium => "200x200>",
 :small => "120x120#",
 :thumb => "75x75#",
 :default_url => "http://www.adtechnology.co.uk/images/UGM-default-user.png"
   }

validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/

Views = Users/index

<%= form_for @user, url: user_path(current_user), html: { method: :put, :multipart => true } do |f| %>
 <p class="editpage">Profile Picture: <%= f.file_field :avatar %></p>
 <%= f.submit "Upload" %>
<% end %> 

Upvotes: 0

Views: 51

Answers (3)

Anna88
Anna88

Reputation: 355

It's better to revert to a single model or if you are using seperate model for avatar then use fields_for concept watch it

Upvotes: 0

David Aldridge
David Aldridge

Reputation: 52376

I think you've just learned that you got some bad advice.

What was the basis for separating them out? It has made your code more complex and therefore error prone.

I think the best step you could take is to revert to a single model.

Upvotes: 0

IngoAlbers
IngoAlbers

Reputation: 5812

You can use do it like this:

Models:

class User < ActiveRecord::Base
  has_one :user_avatar
  accepts_nested_attributes_for :user_avatar, allow_destroy: true
end

class UserAvatar < ActiveRecord::Base
  belongs_to :user

  has_attached_file :avatar, :styles => {
    :medium => "200x200>",
    :small => "120x120#",
    :thumb => "75x75#",
    :default_url => "http://www.adtechnology.co.uk/images/UGM-default-user.png"
  }

  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end

View:

<%= form_for @user, url: user_path(current_user), html: { method: :put, :multipart => true } do |f| %>
  <%= fields_for @user.user_avatar do |user_avatar_form| %>
    <p class="editpage">Profile Picture: <%= user_avatar_form.file_field :avatar %></p>
  <% end %>
  <%= f.submit "Upload" %>
<% end %> 

You can also check http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for and http://guides.rubyonrails.org/form_helpers.html for more information.

Upvotes: 1

Related Questions