Rails Agile Store Basic Flashcards
Mobile Viewport
meta name=”viewport”, content=”width=device-width, initial-scale=1.0” >
Product validation
validates :title, :description, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 1}
validates :title, uniqueness: true
has_attached_file :image, :styles=> {:medium => “300x300>”, :thumb=> “100x100>”}
validates_attachment_content_type :image, :content_type =>[ “image/png” , “image/jpg”, “image/gif” ]
D2: Connecting Products to Carts
Cart Scaffold
$ rails generate scaffold cart
$ rails generate scaffold line_item product:references cart:references
D3: model Cart.rb
model Cart.rb
has_many :line_items, dependent: :destroy
D5: model product.rb
ensure_not_referenced_by_any_line_item
has_many :line_items
before_destroy :ensure_not_referenced_by_any_line_item
private
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base , ‘Line items present’)
return false
end
end
D6: CurrentCart
application_controller.rb
module CurrentCart extend ActiveSupport::Concern private def set_cart @cart = Cart.find(session[:cart_id]) rescue ActiveRecord::RecordNotFound @cart = Cart.create session[:cart_id] = @cart.id end end
D7: Adding a Button
in app/view/store/index.html.erb
%= button_to ‘Add to Cart’, line_items_path(:product_id => product) %>
D8: adding the method in Line_items_controller.rb
depot_f/app/controllers/line_items_controller.rb
include CurrentCart
before_action :set_cart, only: [:create]
def create product = Product.find(params[:product_id]) @line_item = @cart.line_items.build(:product => product)
respond_to do |format| if @line_item.save format.html { redirect_to(@line_item.cart, :notice => 'Line item was successfully created.') } format.js { @current_item = @line_item } format.json { render :show, status: :created, location: @line_item } else format.html { render :action => "new" } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end end
D9: Putting the view for Adding
in app/view/carts/show.html.erb
% @cart.line_items.each do |item| %>
<li>
Task E: A Smarter Cart
$ rails generate migration add_quantity_to_line_item quantity:integer
Task E2: Modify the migration to add default value
#class AddQuantityToLineItem 1 #end #end
Task E3: Add to cart f(x)
in app/model/cart.rb
class Cart :destroy
def add_product(product_id) current_item = line_items.find_by(product_id: product_id) if current_item current_item.quantity += 1 else current_item = line_items.build(product_id: product_id) end current_item end end
Task E5: update the show.html in Cart
in app/view/carts/show.html.erb
<p></p>
Task E6: Create the cart render partial
in app/views/carts/_cart.html.erb
%= render(cart.line_items) %>
Total
%= button_to (‘Empty cart’), @cart, method: :delete, data: { confirm: ‘Are you sure?’ } %>
Task E7: Create new migration
$ rails generate migration combine_items_in_cart
Task E8: Method for adding items or subtracting in the custom migration (Combine UP)
class CombineItemsInCart 1 # remove individual items cart.line_items.where(product_id: product_id).delete_all
# replace with a single item item = cart.line_items.build(product_id: product_id) item.quantity = quantity item.save! end end end end
def self.down
# split items with quantity>1 into multiple items
LineItem.where(“quantity>1”).each do |line_item|
# add individual items
line_item.quantity.times do
LineItem.create cart_id: line_item.cart_id, product_id: line_item.product_id, quantity: 1
end
# remove original item
line_item.destroy
end
end
end