Search code examples
ruby-on-railsassociationshas-one

Has_one association should be a has "only" one association


I have a User and a Gallery model and the following associations:

gallery.rb

attr_accessible :name, :description

belongs_to :user

user.rb

has_one :gallery 

A gallery is created through a form and it is not build on the user creation (I do this because some user won't be allowed to create a gallery)

Here is the gallery controller with the create action:

galleries_controller.rb

def create
  @gallery = Gallery.new(params[:gallery])
  @gallery.user_id = current_user.id # save user_id to gallery
  if @gallery.save
    redirect_to @gallery, :notice => "Your gallery has been successfully created."
  else
    render :action => 'new'
  end
end

1.) My first question is:

when I set up a 1-to-1 association like this one, A user can create as many gallery as he wants. So is it not truly a has "only" one association? (I don't think I get the concept on this. Why is there no error raised?)

2.) My second question:

In order to have only one gallery per user I had a validation on the user_id in the gallery model

validates :user_id, :uniqueness => true

Is it the correct way to avoid many gallery records associated to one user?

EDIT

Thanks to Reuben, I dit it like this:

controller

def new
  if current_user.gallery == nil
    @gallery = current_user.build_gallery
  else
    flash[:error] = "You already have a gallery"
  end
end

def create
  @gallery = current_user.build_gallery(params[:gallery])
  if @gallery.save
    redirect_to @gallery, :notice => "Your gallery has been successfully created."
  else
    render :action => 'new'
  end
end

In the view (new.html.erb)

<% if current_user.gallery == nil %>
  <%= form ... %>
<% end %>

No user_id validation needed


Solution

  • You can put a check in the new action to see if the user already has a gallery and either redirect the user saying they already have a gallery or alert the user that creating a new gallery will destroy their existing one. In the latter case you would also need to check for the existing gallery in the create action and delete it before saving the new one otherwise you will have ownerless galleries filling your database.

    In your views you could check the same and only show the new link if the user does not have a gallery.