Newbie question


#1

Hey all,

I’ve been working with rails for a grand total of 8 hours, and have run
up against the first problem I haven’t been able to adequately solve
using google.

So I’ve got a schema that basically consists of a bunch of researchers.
Each researcher has only one notebook. I’m trying to ensure that only
one notebook can be created for each user. Below is the code I’ve been
using in the create method for my notebook:

existingbook = Notebook.find(:first, params[:researcher_id])
@notebook = Notebook.new(params[:notebook])

respond_to do |format|
  if (existingbook.nil?)
    if @notebook.save
      flash[:notice] = 'Notebook was successfully created.'
      format.html { redirect_to(@notebook) }
      format.xml  { render :xml => @notebook, :status => :created,

:location => @notebook }
else
format.html { render :action => “new” }
format.xml { render :xml => @notebook.errors, :status =>
:unprocessable_entity }
end
else
flash[:error] = ‘A notebook already exists for this user’
format.html { render :action => “new” }
format.xml { render :xml => @notebook.errors, :status =>
:unprocessable_entity }
end
end

The basic idea is to check the notebook table for the researcher id
specified by the user. If a notebook already exists, send an error
message back. Otherwise, create the notebook as usual. However, the
above code doesn’t work like I think it should. Basically what I have
above always allows another notebook to be created (e.g. I can enter
researcher_id of 1 five times in a row without an error). Is there
something I’m missing? Is there any way to check the database to see if
a value exists already before saving it off? I’m probably missing
something simple here, and if anyone has some input I would greatly
appreciate the assistance.


#2

On 13 Feb 2009, at 18:22, Matt Billock wrote:

Each researcher has only one notebook. I’m trying to ensure that only
one notebook can be created for each user. Below is the code I’ve been
using in the create method for my notebook:

existingbook = Notebook.find(:first, params[:researcher_id])

This doesn’t find a notebook with the specified researcher_id. It just
finds a notebook (and thinking about it, how could Notebook.find know
that the parameter you were giving it was a researched_id and not
something else?_

If you check log/development.log while you’re doing this you can see
the sql queries generated which would reveal this.

What you probably meant to write is
Notebook.find_by_researcher_id(params[:researcher_id]) or if you
wanted to be long winded

Notebook.find :first, :conditions => [“researcher_id = ?”,
params[:researcher_id]]

Lastly, take a look at validates_uniqueness_of and be aware of the
race condition inherent in the way it works (your code suffers from
the same problem)

Fred


#3

Frederick C. wrote:

On 13 Feb 2009, at 18:22, Matt Billock wrote:

This doesn’t find a notebook with the specified researcher_id. It just
finds a notebook (and thinking about it, how could Notebook.find know
that the parameter you were giving it was a researched_id and not
something else?_

If you check log/development.log while you’re doing this you can see
the sql queries generated which would reveal this.

What you probably meant to write is
Notebook.find_by_researcher_id(params[:researcher_id]) or if you
wanted to be long winded

Notebook.find :first, :conditions => [“researcher_id = ?”,
params[:researcher_id]]

Lastly, take a look at validates_uniqueness_of and be aware of the
race condition inherent in the way it works (your code suffers from
the same problem)

Fred

Thanks much for the reply! I figured it was something simple like that.
I just implemented the validates_uniqueness_of attribute before coming
back here and it does the job much better than I could :slight_smile:


#4

Hey man. Welcome! First thing, from hereonin, please put more
meaningful subject names. We get lots of noob questions. Second, what
you’d like is belongs_to association. Take a look in
activerecord::base documentation at api.rubyonrails.org

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

On 14/02/2009, at 5:22 AM, Matt Billock
<removed_email_address@domain.invalid


#5

Create a unique index for the foreign key (user_id) in the notebook
table!