Ruby on Rails session[:counter ] increases by two - ruby-on-rails

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

Issue with HomeController showing undefined method

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.

Get “wrong number of arguments” on ruby on rails

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

Ruby on rails method partials?

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.

Ruby: NoMethodError: undefined method `<<' for nil:NilClass

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.

how call method logged_in in rails from model?

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?)

Resources