You are not logged in.
Pages: 1
Anyone want to help out a total programming noob trying to learn RoR? I'm trying to move a variable from my index.rhtml to my model. Normally that's done by the controller but I'm having problems moving the data.
I have a line in my [view] index.rhtml that shows:
<td width="40" align="center"><%= text_field 'product', 'qty_added',
{:size=>3}
I'm not sure how to modify my submit action to capture that 'qty_added' though. Right now I'm just using this:
<%= link_to 'Add to Cart',
{:action => 'add_to_cart', :id => product },
:class => 'addtocart' %><br/>
Which i know is incomplete. But like I said, I'm a total noob. Can anyone help?
Offline
like you said. the controller "moves" data from the view to the model, and vice versa (more or less. occasionally there are times where direct pulls from the model within the view are workable, but not the other way around)
"Be conservative in what you send; be liberal in what you accept." -- Postel's Law
"tacos" -- Cactus' Law
"t̥͍͎̪̪͗a̴̻̩͈͚ͨc̠o̩̙͈ͫͅs͙͎̙͊ ͔͇̫̜t͎̳̀a̜̞̗ͩc̗͍͚o̲̯̿s̖̣̤̙͌ ̖̜̈ț̰̫͓ạ̪͖̳c̲͎͕̰̯̃̈o͉ͅs̪ͪ ̜̻̖̜͕" -- -̖͚̫̙̓-̺̠͇ͤ̃ ̜̪̜ͯZ͔̗̭̞ͪA̝͈̙͖̩L͉̠̺͓G̙̞̦͖O̳̗͍
Offline
I think what you are looking for is a form. (form_tag, form_remote_tag) It generates a post request for a specific controller and then it is up to the controller to decide what to do with the data (calling the model for ex.).
Offline
I think you're right -- a form would post while what I've written is a get. I gutted my index.rhtml to call the form and then in my _form.rhtml I put the following code because I want it to display the product title from the database.
3: <%= text_field 'product', 'title' %></p>
4:
5: <td class="producttitle">
6: <div class="titlename"><%= h(product.title) %></div>
7: </td>
When I do that though I get an error:
undefined local variable or method `product' for #<#<Class:0x4097f2c0>:0x4097f20c>
How does one access database variables from within a form?
This is super frustrating.. all I'm trying to do is take a user-inputted variable from index.rhtml and move it to my model and it's taking me weeks.
Offline
I think you're right -- a form would post while what I've written is a get. I gutted my index.rhtml to call the form and then in my _form.rhtml I put the following code because I want it to display the product title from the database.
3: <%= text_field 'product', 'title' %></p> 4: 5: <td class="producttitle"> 6: <div class="titlename"><%= h(product.title) %></div> 7: </td>
When I do that though I get an error:
undefined local variable or method `product' for #<#<Class:0x4097f2c0>:0x4097f20c>
How does one access database variables from within a form?This is super frustrating.. all I'm trying to do is take a user-inputted variable from index.rhtml and move it to my model and it's taking me weeks.
Hi,
it would be easier to help you if you posted some more complete code examples.
Since I can't see your controllers code I can just assume that you should write @product instead of product.
If you provide more details, we can surely make it work.
Otherwise there are some instructive tutorials on rubyonrails.org.
Offline
Probably the easiest way is for me to post code that works.. This is the code that works to add products to the shopping cart but does not take into account quantity. I would also like to pass quantity to the shopping cart so that in addition to knowing which product the user wants, I also can determine how many they would like.
Here is the View:
<table>
<div class="catalogentry">
<tr>
<td colspan="1" rowspan="2">
<img src="<%= product.image_url %>"/></td>
<td width="80"><b><%=h(product.title) %></b></td>
<td width="160"><%= product.description %></td>
<td width="60" align="center"><%= product.qty_available %></td>
<td width="80" align="center"><%= number_to_currency(product.price) %></td> <td width="40" align="center"><%= text_field 'line_item', 'quantity', {:size=>3}
%> </td>
</tr>
<td></td>
<td></td>
<td valign="top" align="center">in-stock</td>
<td valign="top" align="center">each</td>
<td> <%= link_to 'Add to Cart',
{:action => 'add_to_cart', :id => product },
:class => 'addtocart' %><br/>
</td>
</div>
</table>
Here is the add to cart portion of the controller:
class StoreController < ApplicationController
def index
@products = Product.salable_items
end
def add_to_cart
product = Product.find(params[:id])
@cart = find_cart
@cart.add_product(product)
redirect_to(:action => 'display_cart')
#rescue
# logger.error("Attempt to access invalid product #{params[:id]}")
# redirect_to_index('Invalid Product')
end
Finally, here is the model (cart)
class Cart
attr_reader :items
attr_reader :total_price
def initialize
empty!
end
def add_product(product)
item = @items.find {|i| i.product_id == product.id}
if item
item.quantity += 1
else
item = LineItem.for_product(product)
@items << item
end
@total_price += product.price
end
def empty!
@items = []
@total_price = 0.0
end
end
and model for line_item
class LineItem < ActiveRecord::Base
belongs_to :product
belongs_to :order
def self.for_product(product)
item = self.new
item.product = product
item.quantity = 1
item.unit_price = product.price
item
end
end
It's currently setting the quantity to 1 and incrementing by 1 each time the same product is added to the cart. Let me know if you want to see more of the code. I don't mind posting it all as a zip if you like.
One more piece of info is my database schema which looks like this:
Table: line_items
id
product_id
order_id
quantity
unit_price
Table: orders
id
name
email
address
pay_type
shipped_at
Table: products
id
title
description
image_url
price
qty_available
date_available
date_expires
Table: users
id
name
hashed_password
Thanks everyone..
Offline
As pikass wrote before, you need to use a form.
Just a short example how that could be done in the view:
<%= form_tag :action =>'add_to_cart', :controller => 'store' %>
<%= text_field 'line_item', 'quantity', {:size=>3 } %>
<%= hidden_field 'line_item','product_id', :value=>product.id %>
<%= submit_tag %>
<%= end_form_tag %>
Hope that helps.
Offline
I replaced the index.rhtml in my view with the example you posted above and got this output:
undefined local variable or method `product' for #<#<Class:0x40761d58>:0x40761ca4>
I'm too new to all this programming stuff to really break that down. (I'm also close to brain fried at this stage.) Still, my controller and view are posted above in case you are feeling generous and want to help me further.
Thanks..
Offline
I believe that when you submit a form, all of the values are stored an array called <code>params[]</code>, so you'd want to access your quantity symbol in the function that you're passing control to...in this case <code>add_to_cart</code> in the <code>StoreController</code>.
You'll have to re-write the <code>add_product</code> method as well to accept a quantity along with the product; and it should have a default value of one in case they don't specify a number.
I'm not at my home machine right now, and can't test it out, but the basic idea will be that your <code>add_to_cart</code> function will look something like this:
def add_to_cart
product = Product.find(params[:id])
@cart = find_cart
@cart.add_product(product, params[:quantity])
redirect_to(:action => 'display_cart')
rescue
logger.error("Attempt to access invalid product #{params[:id]}")
redirect_to_index('Invalid Product')
end
and the <code>add_product</code> function in your Cart model will be:
def add_product(product, quantity=1)
item = @items.find {|i| i.product_id == product.id}
if item
item.quantity += quantity
else
item = LineItem.for_product(product)
@items << item
end
@total_price += (product.price * quantity)
end
Hopefully that's correct, but either way it should give you a good idea of what to tweak...
Offline
I think it's getting close. I'm getting an error about moving nil to a fixed number which tells me that the error is probably with the view not passing along the quantity (hence the nil?) ((removing the quantity=1 in the model changed the error to moving nil to a float if I recall))
The exact error is:
nil can't be coerced into Fixnum
Application trace is
/usr/lib/ruby/gems/1.8/gems/activesupport-1.2.5/lib/active_support/whiny_nil.rb:35:in `+'
#{RAILS_ROOT}/app/models/cart.rb:13:in `add_product'
./script/../config/../app/controllers/store_controller.rb:10:in `add_to_cart'
Here is my view code based on jochen's example:
<h3>Currently Available</h3>
<% for product in @products %>
<table>
<div class="catalogentry">
<%= form_tag :action =>'add_to_cart', :controller => 'store' %>
<%= text_field 'line_item', 'quantity', {:size=>3 } %>
<%= text_field 'line_item','product_id', :value=>product.id %>
<%= link_to 'Add to Cart',
{:action => 'add_to_cart', :id => product },
:class => 'addtocart' %>
<%= end_form_tag %>
</div>
</table>
<div class="separator"> </div>
<% end %>
<%= link_to "Show my cart", :action => "display_cart" %>
Offline
Pages: 1