Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 720
benoitr Avatar asked Feb 23 '23 03:02

benoitr


2 Answers

Re your first question: What has_one really does is that it appends the LIMIT 1 clause to the corresponding sql query, and nothing more. That's why, in your case, the user can create as many galleries as they want.

like image 135
Marek Příhoda Avatar answered Mar 02 '23 18:03

Marek Příhoda


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.

like image 45
Reuben Mallaby Avatar answered Mar 02 '23 20:03

Reuben Mallaby