I am studying pragmatic bookshelf lessons. I try to make a session counter.
my store controller is
class StoreController < ApplicationController
def increment_counter
if session[:counter].nil?
session[:counter] = 0
end
session[:counter] += 1
end
def index
#count = increment_counter
#products = Product.all
#cart = current_cart
#time = Time.now
#shown_message = "You've been here #{#count} times" if increment_counter >5
end
end
and my view is
<h5><p><%= #shown_message %></p></h5>..
until 5 times it does not work . but after it starts to count as 5,7,9,11. . what is wrong with my session[:counter]?
You call increment_counter twice in your action : first when setting #count, and then again in your condition for #shown_message.
In complement to ksol answer. Use #count in the last call.
def index
#count = increment_counter
#products = Product.all
#cart = current_cart
#time = Time.now
#shown_message = "You've been here #{#count} times" if #count >5
end
In your store_controller.rb better code like that:
before_action :session_counter
def session_counter
if session[:counter].nil?
session[:counter] = 0
end
session[:counter] += 1
#session_counter = session[:counter]
end
In store.html.erb like that:
<p>
<% if #counter>5 %>
<%= "U have visit the store #{#session_counter} times!" %>
<% end %>
</p>
looks a pretty nice and works easy.
Related
I am trying to pass stored_products from shopify into a Rails app but keep getting a home controller error at https://f588240c.ngrok.io/ i have made updates, with no luck and restarted the server a number of times with no luck.
Any help would be welcomed. Heres the code
class Api::V1::HomeController < ShopifyApp::AuthenticatedController
def index
#products = ShopifyAPI::Product.find(:all, params: { limit: 10 })
#products.each do |product|
StoredProduct.where(shopify_id: product.id)
.first_or_create do |stored_product|
stored_product.shopify_id = product.id
stored_product.shopify_title = product.title
stored_product.shopify_handle = product.handle
stored_product.shopify_image_url = product.image.src
stored_product.shop_id = #shop.id
stored_product.save
product.images.each do |image|
ProductImage.where(shopify_id: image.id)
.first_or_create do |product_image|
product_image.image_url = image.src
product_image.stored_product_id = stored_product_id
product_image.shopify_id = image.id
end
end
end
end
#stored_products = StoredProduct.belongs_to_shop(#shop.id)
end
end
From the authenticated controller
private
def set_shop
#shop = Shop.find_by(id: session[:shopify])
set_locale
end
from the store_products.rb file
class StoredProduct < ApplicationRecord
belongs_to :shop
has_many :product_images
scope :belongs_to_shop, -> shop_id { where(shop_id: shop_id) }
end
For this specific issue/code tutorial, the private set_shop method should be set like follows:
def set_shop
#shop = Shop.find_by(id: session[:shop_id])
set_locale
end
The other answer has params instead of session
The problem is that #shop is nil. The error message says it cannot call the method .id on NilClass.
In the image I can see that you have a shop_id in the params so you might just need to change your code here:
def set_shop
#shop = Shop.find_by(id: params[:shop_id])
set_locale
end
But that depends on your code, so please double check.
wrong number of arguments (given 2, expected 1)
SportsController
class SportsController < ApplicationController
def index
#sport = Sport.all
#events, #errors = Bapi::Inplay.all(query)
end
private
def query
params[:query, {}]
end
end
Sport index.html.erb
<% #sports.each do |sport| %>
<% #events(:sport_id => sport.id).each_slice(2) do |events| %>
I want send each sport.id to #enevts instance variable
Edited :
When send query as hash in SportsController its work!!
class SportsController < ApplicationController
def index
#sport = Sport.all
query = {:sport_id => 1}
#events, #errors = Bapi::Inplay.all(query)
end
private
def query
params[:query, {}]
end
end
Index.html.erb
<% #sports.each do |sport| %>
<% #events.each_slice(2) do |events| %>
params is a hash and method :[] can accept only 1 argument.
def query
params[:query] || {} # Will return :query part or empty Hash if it has nothing
end
I was wondering if it is possible to create a method partial in ruby on rails, for example I have this code;-
#cart = Cart.where(:user_id => current_user.id).first if user_signed_in?
#slots = #cart.slots.first
#slot_list = [#slots.slot_one, #slots.slot_two, #slots.slot_three, #slots.slot_four, #slots.slot_five,
#slots.slot_six, #slots.slot_seven, #slots.slot_eight, #slots.slot_nine, #slots.slot_ten]
#user_products = []
#product = []
#slot_list.each do |item|
if item.nil?
p 'Item empty'
else
#product << item
end
end
#product.each do |item|
items = Product.where(:product_id => item).first
#user_products << items
end
Written in multiple methods to get the #user_products, I was wondering if there was a way so I don't have to write this all the time and possibly run a method or use a partial?
Would it be worth creating a helper that does this and returns the #user_products variable?
I took my own advice and created two helpers, one to return the #user_products and another to return the #total.
I added the names of the methods to our helper_method
helper_method :user_is_admin?, :authenticate_admin!, :product_available?, :get_user_products!, :get_user_total!
then added these two methods at the bottom of the file;-
get_user_products!
def get_user_products!
#cart = Cart.where(:user_id => current_user.id).first if user_signed_in?
#slots = #cart.slots.first
#slot_list = [#slots.slot_one, #slots.slot_two, #slots.slot_three, #slots.slot_four, #slots.slot_five,
#slots.slot_six, #slots.slot_seven, #slots.slot_eight, #slots.slot_nine, #slots.slot_ten]
#user_products = []
#product = []
#slot_list.each do |item|
if item.nil?
p 'Item empty'
else
#product << item
end
end
#product.each do |item|
items = Product.where(:product_id => item).first
#user_products << items
end
return #user_products
end
get_user_total!
def get_user_total!
#total = 0
#cart = Cart.where(:user_id => current_user.id).first if user_signed_in?
#slots = #cart.slots.first
#slot_list = [#slots.slot_one, #slots.slot_two, #slots.slot_three, #slots.slot_four, #slots.slot_five,
#slots.slot_six, #slots.slot_seven, #slots.slot_eight, #slots.slot_nine, #slots.slot_ten]
#user_products = []
#product = []
#slot_list.each do |item|
if item.nil?
p 'Item empty'
else
#product << item
end
end
#product.each do |item|
items = Product.where(:product_id => item).first
#user_products << items
end
#user_products.each do |p|
#total += p.product_price
end
return #total
end
To use these methods inside whatever controller you then do the following;-
#user_products = get_user_products!
#total = get_user_total!
I assume this is in a controller?
What you want is to use plain old Ruby objects (POROs). So, you might have something like this:
class UserProducts
class << self
def get(options={})
#cart = Cart.where(:user_id => current_user.id).first if user_signed_in?
#slots = #cart.slots.first
#slot_list = [
#slots.slot_one,
#slots.slot_two,
#slots.slot_three,
#slots.slot_four,
#slots.slot_five,
#slots.slot_six,
#slots.slot_seven,
#slots.slot_eight,
#slots.slot_nine,
#slots.slot_ten
]
#user_products = []
#product = []
#slot_list.each do |item|
if item.nil?
p 'Item empty'
else
#product << item
end
end
#product.each do |item|
items = Product.where(:product_id => item).first
#user_products << items
end
end
end
Then, in your controller, you'd do something like:
class FooController < ApplicationController
def index
UserProducts.get(user_id: current_user.id)
end
end
So, UserProducts is essentially a service object. I think some people call them use cases. I tend to call them 'managers'. I put them in their own directory as app/managers/user_products.rb.
I get the error "NoMethodError: undefined method `<<' for nil:NilClass" when trying to add an object to an empty array. I think it relates to the array being nil instead of empty, and it's not allowing me to append a new object.
The problem occurs with the last line cashier.rule_set.add(apple_rule). Not sure if I am implementing the RuleSet class and initializing #rules correctly.
class Rule
attr_reader :sku, :quantity, :price
def initialize(sku, quantity, price)
#sku = sku
#quantity = quantity
#price = price
end
end
class RuleSet
attr_accessor :rules
def initalize()
#rules = []
end
def add(rule)
#rules << rule
end
def rule_for_sku(sku)
#rules.detect { |r| r.sku == sku }
end
end
class Product
attr_accessor :name, :price, :sku
def initialize(name, price)
puts "Added #{name}, which costs $#{price} to available inventory."
#name = name
#price = price
#sku = (rand(100000) + 10000).to_s
end
end
class Cashier
attr_accessor :rule_set
def initialize
#cart = []
#total_cost = 0
#rule_set = RuleSet.new
end
def add_to_cart(product)
puts "Added #{product.name} to your cart."
#cart << product
end
def in_cart
#cart.each_with_object(Hash.new(0)) {|item, counts| counts[item] += 1}
end
def checkout
self.in_cart.each do |item, quantity|
rule = self.rule_set.rule_for_sku(item.sku)
if rule.present? && quantity >= rule.quantity
total_cost += item.price
end
end
end
end
##Testing
#Initialize list of available products and costs
apple = Product.new("apple", 5)
banana = Product.new("banana", 2)
grape = Product.new("grape", 3)
apple_rule = Rule.new(apple.sku, 3, 12)
cashier = Cashier.new
cashier.rule_set.add(apple_rule)
You have misspelt initialize in your RuleSet class (initalize) so that method isn't being called and #rules is not being set to an empty array.
actually i use restful-authentication but ai need call method logged_in from MODEL (no controller) distinct of user.
can you help me...
example:
modelx.rb
def price
if logged_in?
#product.price = current_user.prices
else
#product.price = 0
end
end
It's a better design to pass that information in from where you are calling the method.
def price(logged_in = false)
if logged_in
#product.price = current_user.prices
else
#product.price = 0
end
end
Calling it from the controller or view:
#modelx.price(logged_in?)