Hey guys, i ran in some trouble while making an important app for school, and the deadline is so soon, that i took a desperate decision, bother you.. I will put up the code here, and if anyone has a solution, it would mean the world to me and my work. My problem is this line of code li.product = cart_item.product because list_items doesn''t have a column named product, so what the heck? The second is that when they interrogate the db, namely the line_items table, the product column doesn''t show up, as you can see below: depot> sqlite3 -line db/development.sqlite3 SQLite version 3.4.0 Enter ".help" for instructions sqlite> select * from orders; id = 1 name = Dave Thomas address = 123 Main St email = customer-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org pay_type = check created_at = 2008-06-09 13:40:40 updated_at = 2008-06-09 13:40:40 -------------------------------------------------------- sqlite> select * from line_items; id = 1 product_id = 3 order_id = 1 quantity = 1 total_price = 28.5 created_at = 2008-06-09 13:40:40 updated_at = 2008-06-09 13:40:40 sqlite> .quit ------------------------------------------------------- here is the rest of the code that i have , concerning this problems: class CreateOrders < ActiveRecord::Migration def self.up create_table :orders do |t| t.string :name t.text :address t.string :email t.string :pay_type, :limit => 10 t.timestamps end end def self.down drop_table :orders end end class CreateLineItems < ActiveRecord::Migration def self.up create_table :line_items do |t| t.integer :product_id, :null => false, :options => "CONSTRAINT fk_line_item_products REFERENCES products(id)" t.integer :order_id, :null => false, :options => "CONSTRAINT fk_line_item_orders REFERENCES orders(id)" t.integer :quantity, :null => false t.decimal :total_price, :null => false, :precision => 8, :scale => 2 t.timestamps end end def self.down drop_table :line_items end end class Order < ActiveRecord::Base has_many :line_items end class Product < ActiveRecord::Base has_many :line_items # ... class LineItem < ActiveRecord::Base belongs_to :order belongs_to :product end thx a million in advance, radu -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Sat, Dec 19, 2009 at 6:34 AM, radu puspana <radupuspana-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hey guys, > > i ran in some trouble while making an important app for school, and > the deadline is so soon, that i took a desperate decision, bother > you.. > I will put up the code here, and if anyone has a solution, it would > mean the world to me and my work. > > My problem is this line of code li.product = cart_item.product > because list_items doesn''t have a column named product, so what the > heck?I assume that list_items was a typo for line_items. It shouldn''t, it should have an integer column called product_id, which references the key (id) of the product record> The second is that when they interrogate the db, namely the line_items > table, the product column doesn''t show up, as you can see below: > > depot> sqlite3 -line db/development.sqlite3 > SQLite version 3.4.0 > Enter ".help" for instructions > sqlite> select * from orders; > id = 1This is order #1> name = Dave Thomas > address = 123 Main St > email = customer-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org > pay_type = check > created_at = 2008-06-09 13:40:40 > updated_at = 2008-06-09 13:40:40 > -------------------------------------------------------- > sqlite> select * from line_items; > id = 1 > product_id = 3This line item belongs to product #3> order_id = 1And it belongs to order #1> quantity = 1 > total_price = 28.5 > created_at = 2008-06-09 13:40:40 > updated_at = 2008-06-09 13:40:40 > sqlite> .quit > ------------------------------------------------------- > > here is the rest of the code that i have , concerning this problems: > > class CreateOrders < ActiveRecord::Migration > def self.up > create_table :orders do |t| > t.string :name > t.text :address > t.string :email > t.string :pay_type, :limit => 10 > t.timestamps > end > end > def self.down > drop_table :orders > end > end > > class CreateLineItems < ActiveRecord::Migration > def self.up > create_table :line_items do |t| > t.integer :product_id, :null => false, :options => > "CONSTRAINT fk_line_item_products REFERENCES products(id)" > t.integer :order_id, :null => false, :options => > "CONSTRAINT fk_line_item_orders REFERENCES orders(id)" > t.integer :quantity, :null => false > t.decimal :total_price, :null => false, :precision => 8, :scale => 2 > t.timestamps > end > end > def self.down > drop_table :line_items > end > endThis looks pretty normal, although most rails apps don''t use foreign key constraints, but I don''t see a problem here.> class Order < ActiveRecord::Base > has_many :line_itemsThis says that Order expects the line_items table to have an integer order_id field> end > > class Product < ActiveRecord::Base > has_many :line_itemsThis says that Product expects the line_items table to have an integer product_id field> # ... > > class LineItem < ActiveRecord::Base > belongs_to :orderThis pairs up with the association declaration in Order and also expects that the line_items table has an order_id field> belongs_to :productThis pairs up with the association declaration in Product and also expects that the line_items table has an product_id field> endOther than your mistaken expectation that line_items would have a product rather than a product_id field, I''m not sure what your problem is. If you need the foreign key field to be product rather than product_id, you can use the :foreign_key option on the relevant associations to override ActiveRecord''s default, and write a migration to rename the column. But the only reason to do this would be to accomodate an existing non-activerecord app sharing the database/table, and in that case you have much less freedom in changing the DB schema. HTH -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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.
thx a lot rick, for taking you time to answer to my problem yeah, it was a typo it was line_items, instead of list_items. but...still don''tget something, i''m a rails noob what would you expect :( what does rails exactly do when you write li.product cart_item.product ??? and wouldn''t it be more logical to write something like li.product_id = cart_item.product_id ??? thx a lot for all your help, radu On Dec 19, 5:53 pm, Rick DeNatale <rick.denat...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Sat, Dec 19, 2009 at 6:34 AM, radu puspana <radupusp...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hey guys, > > > i ran in some trouble while making an important app for school, and > > the deadline is so soon, that i took a desperate decision, bother > > you.. > > I will put up the code here, and if anyone has a solution, it would > > mean the world to me and my work. > > > My problem is this line of code li.product = cart_item.product > > because list_items doesn''t have a column named product, so what the > > heck? > > I assume that list_items was a typo for line_items. > > It shouldn''t, it should have an integer column called product_id, > which references the key (id) of the product record > > > The second is that when they interrogate the db, namely the line_items > > table, the product column doesn''t show up, as you can see below: > > > depot> sqlite3 -line db/development.sqlite3 > > SQLite version 3.4.0 > > Enter ".help" for instructions > > sqlite> select * from orders; > > id = 1 > > This is order #1 > > > name = Dave Thomas > > address = 123 Main St > > email = custo...-kbbdpT5sCmpWk0Htik3J/w@public.gmane.org > > pay_type = check > > created_at = 2008-06-09 13:40:40 > > updated_at = 2008-06-09 13:40:40 > > -------------------------------------------------------- > > sqlite> select * from line_items; > > id = 1 > > product_id = 3 > > This line item belongs to product #3 > > > order_id = 1 > > And it belongs to order #1 > > > > > quantity = 1 > > total_price = 28.5 > > created_at = 2008-06-09 13:40:40 > > updated_at = 2008-06-09 13:40:40 > > sqlite> .quit > > ------------------------------------------------------- > > > here is the rest of the code that i have , concerning this problems: > > > class CreateOrders < ActiveRecord::Migration > > def self.up > > create_table :orders do |t| > > t.string :name > > t.text :address > > t.string :email > > t.string :pay_type, :limit => 10 > > t.timestamps > > end > > end > > def self.down > > drop_table :orders > > end > > end > > > class CreateLineItems < ActiveRecord::Migration > > def self.up > > create_table :line_items do |t| > > t.integer :product_id, :null => false, :options => > > "CONSTRAINT fk_line_item_products REFERENCES products(id)" > > t.integer :order_id, :null => false, :options => > > "CONSTRAINT fk_line_item_orders REFERENCES orders(id)" > > t.integer :quantity, :null => false > > t.decimal :total_price, :null => false, :precision => 8, :scale => 2 > > t.timestamps > > end > > end > > def self.down > > drop_table :line_items > > end > > end > > This looks pretty normal, although most rails apps don''t use foreign > key constraints, but I don''t see a problem here. > > > class Order < ActiveRecord::Base > > has_many :line_items > > This says that Order expects the line_items table to have an integer > order_id field> end > > > class Product < ActiveRecord::Base > > has_many :line_items > > This says that Product expects the line_items table to have an integer > product_id field> # ... > > > class LineItem < ActiveRecord::Base > > belongs_to :order > > This pairs up with the association declaration in Order and also > expects that the line_items table has an order_id field> belongs_to :product > > This pairs up with the association declaration in Product and also > expects that the line_items table has an product_id field > > > end > > Other than your mistaken expectation that line_items would have a > product rather than a product_id field, I''m not sure what your problem > is. > > If you need the foreign key field to be product rather than > product_id, you can use the :foreign_key option on the relevant > associations to override ActiveRecord''s default, and write a migration > to rename the column. But the only reason to do this would be to > accomodate an existing non-activerecord app sharing the > database/table, and in that case you have much less freedom in > changing the DB schema. > > HTH > > -- > Rick DeNatale > > Blog:http://talklikeaduck.denhaven2.com/ > Twitter:http://twitter.com/RickDeNatale > WWR:http://www.workingwithrails.com/person/9021-rick-denatale > LinkedIn:http://www.linkedin.com/in/rickdenatale-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@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 Sat, Dec 19, 2009 at 1:12 PM, radu puspana <radupuspana-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> thx a lot rick, for taking you time to answer to my problem > yeah, it was a typo it was line_items, instead of list_items. > but...still don''tget something, i''m a rails noob what would you > expect :( > > what does rails exactly do when you write li.product > cart_item.product ???I don''t know how deep you want to get but. Each association in an active record model is represented by some form of association proxy. the belongs_to :product declaration in LineItem dynamically defines two methods, I''m going to use a mix of pseudo-code and ''real'' code which is not exactly what''s there but should be a bit clearer, for details just read the ActiveRecord code in lib/associations.rb, and lib/associations/belongs_to_association def product # code to get the association proxy for the product association, which will be in this case an instance of BelongsToAssociation end def product=(value) association = product # Get the association association.replace(value) association end And the important bit of BelongsToAssociation#replace looks like this: def replace(record) # code to deal with counter caching omitted ... if record.nil? # more counter cache code omitted @target = @owner[@reflection.primary_key_name] = nil else raise_on_type_mismatch(record) # More counter cache code omitted # The next line sets @target (which is the ActiveRecord object which the record value belongs to # based on the value on the rhs of the ''assignment'' which is the parameter record. # The conditional expression deals with the fact that # the value could be either another proxy, as it happens to be in the case you asked about # product = CartItem.product # or just a plain model object as it would be in eg. # product = Product.new(...) @target = (AssociationProxy === record ? record.target : record) # Now we set the foreign key field, but only if the value is already saved and therefore has a primary key. # the primary_key_name and record_id methods deal get the primary key names for the association, and the value # which may be affected by the :foreign_key option. # The @owner instance variable refers to the model instance which has this BelongsToAssociation, # which in this case is a LineItem @owner[@reflection.primary_key_name] = record_id(record) unless record.new_record? # The next line marks the association as dirty, so that it will be updated when the record is saved. @updated = true end # this marks the association as being loaded, so that the read accessor knows not to do a SQL request loaded record end There is also some magic I won''t go into which handles cases like this li.product = Product.new() # Note tthis does not save the new product, so it doesn''t have an id yet, so li.product_id can''t be set, until li.save Which causes the Product referenced by the belongs_to association to be saved so that the product_id field in the lineitem can be saved.> > and wouldn''t it be more logical to write something like li.product_id > = cart_item.product_id ???While that''s certainly possible, it isn''t using AR to its value as an Object Relational Mapper. The whole point of AR is to let you think of models as Ruby objects rather than database tables. While you can get closer to whats happening in the SQL, even going so far as writing custom SQL statements, that should be done as a last resort IMHO, although I must admit that using product_id vs. product can be useful in some cases, and is just a small step down that slippery slope. <G> -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.