Forum: Ruby on Rails Models, find not from database??? really need help :(

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.
Eb3ba763011e18aa46fdf0b4b39e65a6?d=identicon&s=25 abusiek (Guest)
on 2008-11-17 07:46
(Received via mailing list)
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
9b4c04c050122bcea16a6f3376d680fa?d=identicon&s=25 Daniel Bush (danb)
on 2008-11-17 08:44
(Received via mailing list)
On Nov 17, 5:45 pm, abusiek <abus...@gmail.com> 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 Bush
Eb3ba763011e18aa46fdf0b4b39e65a6?d=identicon&s=25 abusiek (Guest)
on 2008-11-17 09:38
(Received via mailing list)
On Nov 17, 8:43 am, Daniel Bush <dlb.id...@gmail.com> 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 Bush

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 ...
9b4c04c050122bcea16a6f3376d680fa?d=identicon&s=25 Daniel Bush (danb)
on 2008-11-17 13:07
(Received via mailing list)
On Nov 17, 7:37 pm, abusiek <abus...@gmail.com> 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 Bush
Eb3ba763011e18aa46fdf0b4b39e65a6?d=identicon&s=25 abusiek (Guest)
on 2008-11-18 00:54
(Received via mailing list)
On Nov 17, 1:05 pm, Daniel Bush <dlb.id...@gmail.com> 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 Bush
>
> > 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 Bush

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
This topic is locked and can not be replied to.