Forum: Ruby on Rails Newbie question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Matt B. (Guest)
on 2009-02-13 20:22
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.
Frederick C. (Guest)
on 2009-02-13 21:07
(Received via mailing list)
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
Matt B. (Guest)
on 2009-02-13 21:30
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 :)
Julian L. (Guest)
on 2009-02-14 07:25
(Received via mailing list)
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
CsabaBona (Guest)
on 2009-02-14 12:13
(Received via mailing list)
Create a unique index for the foreign key (user_id) in the notebook
table!
This topic is locked and can not be replied to.