# Find primary key via object attribute

**URL:** <https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445>\
**Category:** Rails\
**Created:** [December 26, 2006, 11:34pm UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445 "2006-12-26T23:34:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jkay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b4bc9f/32.png) [@jkay](https://www.ruby-forum.com/u/jkay)\
**Post date:** [December 26, 2006, 11:34pm UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445/1 "2006-12-26T23:34:49Z")

</div>

## I’m having a hard time wrapping my head around on implementing something like this:

class Student \< ARB  
has\_many: attendances

class Attendance \< ARB  
belongs\_to: student

* * *

class AttendancesController \< ApplicationController  
def check\_in  
end

def create  
@attendance = Attendance.new(params[:attendance])

```
respond_to do |format|
  if @attendance.save
    flash[:notice] = 'You have successfully checked in.'
    format.html { redirect_to :action => "check_in" }
  else
    format.html { render :action => "check_in" }
  end
end

```

end  
end

* * *

The Student table has a column named ‘idn’.  
The Attendance table has a column named ‘student\_id’ and a ‘created\_on’  
column.

This is what I’ve got so far: The student “checks in” by typing in their  
IDN number into a text\_field in the ‘check\_in’ view. After hitting  
‘submit’ the create method is invoked and the IDN number that the  
student submitted is entered into the student\_id field in the Attendance  
table. This is what I would like to do: When the student submits their  
IDN number, rails searches for the number in the idn column in the  
student table. After locating it, the primary key for that IDN number is  
entered into the student\_id column in the Attendance table. If there is  
no matching IDN then of course an error is invoked.

What would be the best way to do this? before\_save method in the  
Attendance model? I’m pretty much clueless. Sorry for the long  
explanation but I wanted to be as detailed as possible. Any help would  
be very appreciated.

---

<div class="post-metadata">

**Author:** ![jkay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b4bc9f/32.png) [@jkay](https://www.ruby-forum.com/u/jkay)\
**Post date:** [December 27, 2006, 6:12am UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445/2 "2006-12-27T06:12:53Z")

</div>

You can do this in your create method create:

#use AR helper find method to cut to the chase  
@student = Student.find\_by\_idn(params[:idn])

#create a new attendance and link the records  
attn = Attendence.new  
@attn.student = @student  
@attn.save

---

<div class="post-metadata">

**Author:** ![jkay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b4bc9f/32.png) [@jkay](https://www.ruby-forum.com/u/jkay)\
**Post date:** [December 27, 2006, 6:27am UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445/3 "2006-12-27T06:27:43Z")

</div>

In your migration make sure to set :unique =\> true for the idn like  
this:

t.column :idn, :integer, :null =\> false, :unique =\> true

AND validate it in your model:

Class Student  
validates\_uniqueness\_of :idn  
validates\_presence\_of :idn

---

<div class="post-metadata">

**Author:** ![jkay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b4bc9f/32.png) [@jkay](https://www.ruby-forum.com/u/jkay)\
**Post date:** [December 27, 2006, 7:49am UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445/4 "2006-12-27T07:49:16Z")

</div>

Thanks for the reply! I keep getting an error like this:  
ActiveRecord::StatementInvalid in AttendancesController#create

Mysql::Error: #23000Column ‘student\_id’ cannot be null: INSERT INTO  
attendances (`created_on`, `student_id`) VALUES(‘2006-12-27 00:40:05’,  
NULL)

I can’t figure out why the idn parameter doesn’t pass through. Here is  
my ‘check\_in’ view:

\<%= error\_messages\_for :attendance %\>

\<% form\_for :attendance, :url =\> { :action =\> :create } do |form| %\>  
\<%= form.text\_field :idn %\>

\<%= submit\_tag 'Check In' %\>

\<% end %\>

Here is my newly updated AttendancesController:

class AttendancesController \< ApplicationController  
def check\_in  
end

def create  
#use AR helper find method to cut to the chase  
@student = Student.find\_by\_idn(params[:idn])

```
#create a new attendance and link the records
@attn = Attendance.new
@attn.student = @student
@attn.save

respond_to do |format|
  if @attn.save
    flash[:notice] = 'You have successfully checked in.'
    format.html { redirect_to :action => "check_in" }
  else
    format.html { render :action => "check_in" }
  end
end

```

end

end

I changed my migration like you suggested. Thanks for the help so far, I  
knew this would look easier than I imagined.

---

<div class="post-metadata">

**Author:** ![jkay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b4bc9f/32.png) [@jkay](https://www.ruby-forum.com/u/jkay)\
**Post date:** [December 31, 2006, 6:26am UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445/5 "2006-12-31T06:26:19Z")

</div>

Okay this is driving me crazy. I keep getting the same error. I deleted  
the @attn.save line so there is no duplication. A record is not getting  
saved in the database. I did however get a record to be saved via the  
console as follows:

> > a = Attendance.new  
> > s = Student.find\_by\_idn(1546)  
> > a.student = s  
> > a.save  
> > student doesn’t exist
> 
> > s.save  
> > true

How can I replicate this in my app?

---

<div class="post-metadata">

**Author:** ![jkay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b4bc9f/32.png) [@jkay](https://www.ruby-forum.com/u/jkay)\
**Post date:** [December 31, 2006, 10:49am UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445/6 "2006-12-31T10:49:08Z")

</div>

Okay I got the correct student\_id being saved into the database with the  
following method in the Attendance model:

def before\_create  
self.student = Student.find\_by\_idn(student\_id)  
end

I have another problem now. If the IDN is not found or doesn’t exist,  
the student\_id attribute for the Attendance object returns nil and  
brings up the same error as before (the student\_id cannot be NULL). How  
can I get the nice looking error messages that you often see for simple  
validations?  
It would say something like “#{student\_id} is not a valid IDN” above the  
check in form.

---

<div class="post-metadata">

**Author:** ![jkay](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/b4bc9f/32.png) [@jkay](https://www.ruby-forum.com/u/jkay)\
**Post date:** [December 27, 2006, 9:54pm UTC](https://www.ruby-forum.com/t/find-primary-key-via-object-attribute/80445/7 "2006-12-27T21:54:26Z")

</div>

> Thanks for the reply! I keep getting an error like this:  
> ActiveRecord::StatementInvalid in AttendancesController#create
> 
> Mysql::Error: #23000Column ‘student\_id’ cannot be null: INSERT INTO  
> attendances (`created_on`, `student_id`) VALUES(‘2006-12-27 00:40:05’,  
> NULL)

1. Is a record created in your database or not?

2. If the student\_id is NULL, then perhaps it is because @student is  
also null. Try doing the create function in the console step by step to  
see what is happening.

3. check development.log for more info on what is happening under the  
hood.

> ```
> #create a new attendance and link the records
> @attn = Attendance.new
> @attn.student = @student
> @attn.save
> 
> respond_to do |format|
> if @attn.save
> flash[:notice] = 'You have successfully checked in.'
> 
> ```

This will try to save @attn twice. You save it directly and then save  
again if @attn. Delete one of the save lines.
