How exactly do you do arithmetic operations in the controller?
I've tried this
def choose
rand_id = rand(Gif.count)
#gif1 = Gif.first(:conditions => [ "id >= ?", rand_id])
#gif2 = Gif.first(:conditions => [ "id >= ?", rand_id])
if #gif1.id == #gif2.id
#gif2 = Gif.first(:order => 'Random()')
end
total = #gif1.votes+#gif2.votes
number_one = #gif1.votes/total*100
number_two = #gif2.votes/total*100
#gif1.update_attribute(:votes, number_one)
#gif2.update_attribute(:votes, number_two)
end
class Gif < ActiveRecord::Base
before_save :default_agree_count
def default_agree_count
self.agree = 1
self.votes = 1
end
VALID_REGEX = /http:\/\/[\S]*\.gif$/
attr_accessible :link, :votes, :agree
acts_as_votable
validates :link, presence: true, format: {with: VALID_REGEX}, uniqueness: {case_sensitive: false}
end
However, it says that +, /, * are all unknown operators. I've also tried doing them within like such #gif1.agree = '#gif1.votes+1' with and without '. Any ideas?
Thanks!
I suppose you are using Acts As Votable gem.
Basically it works as follows:
#post = Post.new(:name => 'my post!')
#post.save
#post.liked_by #user
#post.votes.size # => 1
So try replacing .votes with .votes.size in your code.
E.g.:
total = #gif1.votes.size + #gif2.votes.size
Further to #ilyai's answer (which I +1'd) (I don't have much experience with the Acts As Votable gem), you can perform any calculations you want in your controllers
Here's some refactoring for you:
.first
def choose
Gif.update_votes
end
class Gif < ActiveRecord::Base
before_save :default_agree_count
def default_agree_count
self.agree = 1
self.votes = 1
end
def self.update_votes
rand_id = rand count #-> self.count?
gif = where("id >= ?", rand_id)
gif1 = gif[0]
gif2 = gif[1]
if gif1.id == gif2.id
gif2 = where(order: 'Random()').first
end
total = (gif1.votes) + (gif2.votes)
number_one = ((gif1.votes /total) * 100)
number_two = ((gif2.votes / total) * 100)
gif1.update_attribute(:votes, number_one)
gif2.update_attribute(:votes, number_two)
end
VALID_REGEX = /http:\/\/[\S]*\.gif$/
attr_accessible :link, :votes, :agree
acts_as_votable
validates :link, presence: true, format: {with: VALID_REGEX}, uniqueness: {case_sensitive: false}
end
Related
I get this error on my posts index page :
This the model :
class Post < ApplicationRecord
include Filterable
belongs_to :region
belongs_to :category
belongs_to :topic
validates :title, presence: true, length: { maximum: 500 }
validates :content, presence: true
validates :published_at, presence: true
translates :title, :content, :slug, touch: true, fallbacks_for_empty_translations: true
has_attached_file :image, styles: { thumb: "100x70#", featured: "1560x868#", small: "760x868#", big: ">1600x1600" }
validates_attachment :image, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
validates_attachment_presence :image
scope :published, -> (published) { where(published: (['true', true].include? published)).order(featured: :desc, published_at: :desc) }
scope :published_until_now, -> { where("published_at < ?", Time.now).merge(Post.published(true)) }
scope :topic, -> (topic_id) {
joins(:topic).where('topic_id = ?', topic_id) }
scope :category, -> (post_category) {
joins(:category).where('category_id = ?', post_category) }
scope :match, -> (search_term) {
with_translations(I18n.locale).where('content like ? or title like ?', "%#{search_term}%", "%#{search_term}%") }
self.per_page = 10
after_save :unfeature_older_posts, if: Proc.new { |post| post.featured? }
extend FriendlyId
friendly_id :title, use: :globalize
def unfeature_older_posts
featured_posts = Post.where(featured: true).where.not(id: id).order(published_at: :desc)
if featured_posts.size == 1
featured_posts.last.update(featured: false)
end
end
end
This the controller :
class PostsController < ApplicationController
before_action :get_pages_tree, :get_privacy_policy, only: [:index, :show]
def index
#filters = params.slice(:topic, :category)
#posts = Post.published_until_now
.filter(#filters)
.paginate(:page => params[:page], per_page: 11)
end
def show
#post = Post.friendly.find(params[:id])
end
end
and filter is defined here :
module Filterable
extend ActiveSupport::Concern
module ClassMethods
def filter(filtering_params)
results = self.where(nil)
filtering_params.each do |key, value|
results = results.public_send(key, value) if value.present?
end
results
end
end
end
I'm not sure where to go from here. I recently upgraded to Ruby on Rails 5 and Ruby 2.7.0, I don't know if it's related.
Try replacing module ClassMethods with class_methods do.
If it works, then please keep in mind:
filter method comes from Ruby. It's defined in Array. As you can see in the doc, filter method on Array takes no argument. That's the direct cause of the error you see.
In Rails, when methods on Array are called on ActiveRecord object (in your case, Post.published_until_now) and when methods cannot be found on a model, it automatically converts itself into an Array. So, it calls filter method on Array. Generally, you don't want to define methods such as filter which is confusing.
I'm making a payroll system for pay salaries. I only need to choice a month, a year and press "create payrolls", and create payrolls for all the teachers
mockup
I created the method "create" in payroll_controller.rb:
Payroll_Manager.new(params[:month], params[:year]).crear_liquidaciones_del_periodo()
The Payroll_Manager is in the file app/helpers/payroll_manager.rb
class Payroll_Manager < PayrollsController
def initialize(month, year)
#month = month
#year = year
end
def crear_liquidaciones_del_periodo
Teachers.each do |t|
t.payrolls.create(#month, #year)
end
end
end
And finally, I have the codel payroll.rb
class Payroll < ActiveRecord::Base
belongs_to :teacher
has_many :payroll_lines
def period
period = month + " " + year
end
validates :month, presence: true
validates :year, presence: true
class Payroll < ActiveRecord::Base
#gross_total, retention_total, neto_total
before_save :calculate_payroll
private
def calculate_payroll
calculate_gross_total
calculate_retention_total
calculate_net_total
end
def calculate_gross_total
self.gross_total = 0
## Concepto.where(type: 1)
haberes = Concepts.all.select{ |c| c.type == 1 }
haberes.each do |h|
parametros_para_linea = {concept_id: h.id, subtotal: h.amount}
self.payroll_line.create(parametros_para_linea)
self.gross_total += h.amount
end
end
def calculate_retention_total
self.retention_total = 0
## Concepto.where(type: 0)
retencion = Concepts.all.select{ |c| c.type == 0 }
retencion.each do |r|
parametros_para_linea = {concept_id: h.id, subtotal: h.amount}
self.payroll_line.create(parametros_para_linea)
self.retention_total += r.amount
end
end
def calculate_net_total
self.net_total = gross_total - retention_total
end
end
end
...When I click the "create payroll" button, I have the error:
uninitialized constant Payroll_Manager::Teachers
enter image description here
Please, help me.
Your class definition in payroll_manager.rb should be PayrollManager, not Payroll_Manager.
I think it is really basic question, but I cannot find solution.
I have simple help method:
def getProperNutrientValue(meal)
result = 0
if meal.ingredients.empty?
result
else
meal.ingredients.each do |i|
result += (i.quantity * #meal.products.find(i.product_id).calorific) / 100
end
result
end
end
Where "calorific" is an attribute in Product model.
class Product < ActiveRecord::Base
has_many :ingredients
has_many :meals, :through => :ingredients
validates :calorific, :numericality => true, :allow_nil => true
validates :water, :numericality => true, :allow_nil => true
I want to DRY this function, and set attribute as a variable. Then I will be can use this function for example for water attribute.
So I want to achieve something like that:
def getProperNutrientValue(meal, attribute)
result = 0
if meal.ingredients.empty?
result
else
meal.ingredients.each do |i|
result += (i.quantity * #meal.products.find(i.product_id).attribute) / 100
end
result
end
end
But of course it doesn't work... How can I fix it?
You can use send(method_name) method. I don't understand the logic behind using #meal variable. Either way there are some options to improve your code, for example:
def getProperNutrientValue(meal, attribute)
result = 0
meal.ingredients.each do |i|
result += (i.quantity * #meal.products.find(i.product_id).send(attribute).to_i) / 100
end
result
end
getProperNutrientValue(meal, :calorific)
class Reservation < ActiveRecord::Base
validates :table, presence: true
validates :start, presence: true
validates :finish, presence: true
validate :checking_the_time, :uniqueness_reservation
scope :tables, ->(table) { where("'reservations'.'table' = ? ", table) }
def checking_the_time
if start >= finish
errors.add(:finish, "Invalid time range")
end
end
def uniqueness_reservation
unless Reservation.diapazone(start, finish).tables(table).where.not(id: id).empty?
errors.add(:booked_from, 'Invalid period.')
end
end
private
def self.diapazone(start, finish)
where("(start >= :s AND finish <= :f) OR (start <= :s AND finish >= :s)
OR (start <= :f AND finish >= :f)",
{s: start, f: finish})
end
end
How to refactor the validation checks on entering the order in the order that has already been created?
I will be grateful for the advice, if you can with an example.
theres an excerpt of my code:
module Configuracao
extend self
class Key
include ActiveModel::Validations
attr_accessor :name, :type, :default, :validations, :group, :available_values
def initialize(params)
params.symbolize_keys!.assert_valid_keys(:name, :type, :default, :validations, :group, :available_values)
#group = params[:group]
#name = params[:name]
#type = params[:type]
#available_values = params[:available_values]
#default = params[:default]
#validations = params[:validations]
#in this way each validation is being added for all keys
Configuracao::Key.class_eval do
validates :value, params[:validations]
end
end
end
end
so for every instance key i will have a diferent validation passed in a hash, example:
Key.new( validations: { presence: true, numericality: true } )
Key.new( validations: { length: { maximum: 30 } } )
There's a way to do it?
well i found a solution, maybe not so elegant or best way to do, but it works
def initialize(params)
params.symbolize_keys!.assert_valid_keys(:name, :type, :default, :validations, :group, :available_values)
#group = params[:group]
#name = params[:name]
#type = params[:type]
#available_values = params[:available_values]
#default = params[:default]
##current_validations = nil
##current_validations = #validations = params[:validations]
class << self
validates :value, ##current_validations unless ##current_validations.blank?
end
end
now each time i instantiate a Key, the class will be modified only for that instance
Will this work?
...
validates :all_hash_validations_pass
...
def all_hash_validations_pass
...iterate through the hash here, and validate each of them
end
If not, you should be able to use a custom validator for more control.