# Models, find not from database? really need help :(

**URL:** <https://www.ruby-forum.com/t/models-find-not-from-database-really-need-help/153434>\
**Category:** Rails\
**Created:** [November 17, 2008, 7:46am UTC](https://www.ruby-forum.com/t/models-find-not-from-database-really-need-help/153434 "2008-11-17T07:46:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![abusiek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@abusiek](https://www.ruby-forum.com/u/abusiek)\
**Post date:** [November 17, 2008, 7:46am UTC](https://www.ruby-forum.com/t/models-find-not-from-database-really-need-help/153434/1 "2008-11-17T07:46:30Z")

</div>

Hi!

I’m struggling with this for a while and i’m new to rails so it’s  
quite frustrating 😉

I need to create new model object based on old one with only few  
changes.

I have desings -\> has many -\> lines -\> has\_many -\> fields

I’ve got input from user in array like this:

field =\>[  
line\_id =\>[fiel\_id =\> field\_value]  
]

so I iterate:

input[:field].each do |line\_id, line|  
line.each do |field\_id, field\_value|  
design.lines.find(line\_id).fields.find(field\_id).value =  
field\_value  
design.lines.find(line\_id).fields.find(field\_id).something =  
field\_value  
end  
end

and when i debug(design) there is no change. I assume it’s becouse  
find gets data from database again and again.

Is there any solution for my problem?

Adrian

---

<div class="post-metadata">

**Author:** ![abusiek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@abusiek](https://www.ruby-forum.com/u/abusiek)\
**Post date:** [November 17, 2008, 8:44am UTC](https://www.ruby-forum.com/t/models-find-not-from-database-really-need-help/153434/2 "2008-11-17T08:44:26Z")

</div>

On Nov 17, 5:45 pm, abusiek [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’ve got input from user in array like this:  
> field\_value  
> design.lines.find(line\_id).fields.find(field\_id).something =  
> field\_value  
> end  
> end

You’re finding stuff and assigning new values to what was found but  
not saving these changes back to the db as far as I can tell here.  
Retrieve the field once  
field=design.lines.find(line\_id).fields.find(field\_id)  
update its values and then save it  
field.something = …  
field.save (or field.save!)  
You’re not creating anything new, just updating old.

If you want a new field, you’ll need to create it:  
design.lines.find(line\_id).fields.push(Field.new({hash-of-  
attributes}))  
This will add a new field to design’s line with line\_id.

You could probably do something like  
new\_field=Field.new(field.attributes)  
to create a new field with the same attributes as the existing  
‘field’, alter  
its values as required and then push it onto the fields collection:  
design.lines.find(line\_id).fields.push(Field.new(new\_field))

Be careful with names like ‘field’ - I don’t know if they’ll clash  
with rails names.  
Maybe also consider not chaining all those ‘finds’ together in one  
line.  
Find each thing and store it in a local variable or an instance  
variable so  
you won’t have to get it again during the action.

–  
Daniel B.

---

<div class="post-metadata">

**Author:** ![abusiek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@abusiek](https://www.ruby-forum.com/u/abusiek)\
**Post date:** [November 17, 2008, 9:38am UTC](https://www.ruby-forum.com/t/models-find-not-from-database-really-need-help/153434/3 "2008-11-17T09:38:22Z")

</div>

On Nov 17, 8:43 am, Daniel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > changes.
> 
> not saving these changes back to the db as far as I can tell here.  
> This will add a new field to design’s line with line\_id.  
> Maybe also consider not chaining all those ‘finds’ together in one  
> line.  
> Find each thing and store it in a local variable or an instance  
> variable so  
> you won’t have to get it again during the action.
> 
> –  
> Daniel B.

I followed your suggestion and write this code:

1 new\_design = Design.new design.attributes  
2 design.background.colour\_id = 123  
3 new\_design.background = Background.new  
design.background.attributes  
4 lines = design.lines  
5 for line in lines  
6 new\_line = Line.new line.attributes  
7 fields = line.fields  
8 for field in fields  
9 field.value = input\_data[:field][line.id][field.id]  
10 new\_field = Field.new field.attributes  
11 new\_line.fields.push(new\_field)  
12 end  
13 new\_design.lines.push(new\_line)  
14 end

and now I’v got error that i have nil object in line 5, 8, 9 so it’  
seems that rails think’s design has no lines.

but when I type debug (lines) after line 4 it prints me some lines …

---

<div class="post-metadata">

**Author:** ![abusiek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@abusiek](https://www.ruby-forum.com/u/abusiek)\
**Post date:** [November 18, 2008, 12:54am UTC](https://www.ruby-forum.com/t/models-find-not-from-database-really-need-help/153434/4 "2008-11-18T00:54:49Z")

</div>

On Nov 17, 1:05 pm, Daniel B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > > I’m struggling with this for a while and i’m new to rails so it’s  
> > > > line\_id =\>[fiel\_id =\> field\_value]  
> > > > end
> 
> > > design.lines.find(line\_id).fields.push(Field.new(new\_field))  
> > > Daniel B.
> 
> > 10 new\_field = Field.new field.attributes  
> > are just part of the looping which means there are lines and each line  
> > I didn’t mean to break everything up into separate assignments;  
> > whatever you think is best.
> 
> –  
> Daniel B.

Thanks a lot for your help.

Your guess about message error was right 🙂 i should write input\_data  
[:field][line.id.to\_s] instead input\_data[:field][:line.id].  
Index of array is type of string and my id from database is int and  
there is my error.

My code was so ugly because I’ve tried to use simpliest commands for  
easier debug 😉 now when everything is ok it looks like this:

design.background.colour = input\_data[:bcolor] unless input\_data  
[:bcolor].blank?  
for line in design.lines  
for field in line.fields  
field.value = input\_data[:field][line.id.to\_s]  
[field.id.to\_s]  
field.colour = “#”+input\_data[:fieldcolor][field.id.to\_s]  
unless input\_data[:fieldcolor][field.id.to\_s].\>blank?  
field.size\_id = input\_data[:sizeselect][field.id.to\_s]  
field.font\_id = Font.find\_by\_name(input\_data[:fontselect]  
[field.id.to\_s])  
end  
end  
new\_design = design.clone :include =\> [:background, {:lines  
=\> :fields}]  
return new\_design

Thanks a lot again

Adrian

---

<div class="post-metadata">

**Author:** ![abusiek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/838e76/32.png) [@abusiek](https://www.ruby-forum.com/u/abusiek)\
**Post date:** [November 17, 2008, 1:07pm UTC](https://www.ruby-forum.com/t/models-find-not-from-database-really-need-help/153434/5 "2008-11-17T13:07:42Z")

</div>

On Nov 17, 7:37 pm, abusiek [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > design.lines.find(line\_id).fields.push(Field.new({hash-of-  
> > Be careful with names like ‘field’ - I don’t know if they’ll clash  
> > I followed your suggestion and write this code:
> 
> 1 new\_design = Design.new design.attributes

There’s actually a ‘clone’ method which is probably better than what I  
suggested before.  
new\_design = design.clone  
But don’t forget that you’ll need to save it at some point.

> 11 new\_line.fields.push(new\_field)  
> 12 end  
> 13 new\_design.lines.push(new\_line)  
> 14 end
> 
> and now I’v got error that i have nil object in line 5, 8, 9 so it’  
> seems that rails think’s design has no lines.

I’m guessing it’s line 9 and it has something to do with input\_data  
[:field] or input\_data[:field][line.id] that’s returning nil. 5 and 8  
are just part of the looping which means there are lines and each line  
does have fields.

You could compress your code a little eg  
design.lines.each do |line|  
new\_line = line.clone  
…  
line.fields.each do |field|  
…  
end  
end  
I didn’t mean to break everything up into separate assignments;  
whatever you think is best.

–  
Daniel B.
