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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Bush
2008-Nov-17 07:43 UTC
Re: Models, find not from database??? really need help :(
On Nov 17, 5:45 pm, abusiek <abus...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> 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 > endYou''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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Nov 17, 8:43 am, Daniel Bush <dlb.id...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Nov 17, 5:45 pm, abusiek <abus...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > 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 > > 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 BushI 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 ... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Daniel Bush
2008-Nov-17 12:05 UTC
Re: Models, find not from database??? really need help :(
On Nov 17, 7:37 pm, abusiek <abus...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Nov 17, 8:43 am, Daniel Bush <dlb.id...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > On Nov 17, 5:45 pm, abusiek <abus...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > 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 > > > 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 > > I followed your suggestion and write this code: > > 1 new_design = Design.new design.attributesThere''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.> 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. >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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Nov 17, 1:05 pm, Daniel Bush <dlb.id...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Nov 17, 7:37 pm,abusiek<abus...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > On Nov 17, 8:43 am, Daniel Bush <dlb.id...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > On Nov 17, 5:45 pm,abusiek<abus...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > 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 > > > > 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 > > > 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. > > > > > 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. > > 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 BushThanks 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 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---