element of array destroy params - ruby-on-rails

I have found in my project this piece of code:
Project.all.each do |pr|
if !pr.active
pr.destroy(nil)
end
end
What does de nil in pr.destroy(nil) means?

Related

Find a best way to work with redis cache on rails

I try to use Redis to cache on rails, but I get a challenge when trying to cache multi-language. Because my Redis needs to be cached with table_translations
I try with some code, but I don't think this is the best way
I have the instance variable to work with Erb template
def index
#posts = fetch_posts
#translations = fetch_translations
puts #posts
puts #translations
end
and Redis fetch like this
private
def fetch_posts
begin
posts = $redis.get "posts"
if posts.nil?
posts = []
Post.all.order("id ASC").each do |post|
posts << post
end
posts = posts.to_json
$redis.set "posts", posts
end
posts = JSON.load posts
rescue => error
puts error.inspect
posts = Post.all
end
posts
end
def fetch_translations
begin
translations = $redis.get "translations"
if translations.nil?
translations = []
Post.all.order("id ASC").each do |post|
post.translations.order("locale ASC").each do |translation|
translations << translation
end
end
translations = translations.to_json
$redis.set "translations", translations
end
translations = JSON.load translations
rescue => error
puts error.inspect
translations = Post.all
end
translations
end
I do that because I need to get all language version of a post, so I make a Redis key for translate
and my output:
{"id":1,"slug":"hello-world","thumb_url":"thumbs/null","thumb_file_name":null,"thumb_content_type":null,"thumb_file_size":null,"thumb_updated_at":null,"featured":false,"hidden":false,"created_at":"2019-04-18T07:05:09.117Z","updated_at":"2019-04-18T07:27:55.830Z"}
{"title":"Xin chao","description":"Day la bai viet dau tien, duoc viet tu rails CMS","body":"xin chao cac ban"}
{"title":"Hello World","description":"This is first post from rails CMS","body":"Hello every body"}
I find the best solution to make my output into a key, like this:
{"id":1,"slug":"hello-world","thumb_url":"thumbs/null","thumb_file_name":null,"thumb_content_type":null,"thumb_file_size":null,"thumb_updated_at":null,"featured":false,"hidden":false,"created_at":"2019-04-18T07:05:09.117Z","updated_at":"2019-04-18T07:27:55.830Z","title":"Xin chao","description":"Đay la bai viet đau tien, đuoc viet tu rails CMS","body":"xin chao cac ban"}
{"id":1,"slug":"hello-world","thumb_url":"thumbs/null","thumb_file_name":null,"thumb_content_type":null,"thumb_file_size":null,"thumb_updated_at":null,"featured":false,"hidden":false,"created_at":"2019-04-18T07:05:09.117Z","updated_at":"2019-04-18T07:27:55.830Z",title":"Hello World","description":"This is first post from rails CMS","body":"Hello every body"}
My code can work correctly, but I need your help to make it better, please help me to improve my skills
Thank for your help
You can use the built in Rails cache handler, this way you won't need to handle .nil? calls to cache keys.
private
def fetch_posts
posts = Rails.cache.fetch("posts") do
begin
Post.all.order("id ASC").as_json
rescue => error
puts error.inspect
Post.all
end
end
posts
end
def fetch_translations
translations = Rails.cache.fetch("translations") do
begin
Post.all.order("id ASC").map do |post|
post.translations.order("locale ASC").as_json
end.flatten
rescue => error
puts error.inspect
Post.all
end
end
translations
end
I found the solution by follow this stuff How do you add an array to another array in Ruby and not end up with a multi-dimensional result?
concept is flatten all attr in two array and then Hash again this into new array
def fetch_posts
posts = []
Post.all.order("id ASC").each do |post|
post.translations.each do |translation|
posts << [*post.attributes.slice('slug','thumb_url'),*JSON.parse(translation.to_json)].to_h
end
end
end
Hope this help to anyone have question same to me :)

Rails views output is different than Puma web server logs

I have a ruby script called abc.rb in rails config/initializers
require 'http'
class Abc
def initialize(url)
#url = url
#doc = web_lookup(#url)
end
def web_lookup(url_to_open)
begin
return Nokogiri::HTML(HTTP.get(url_to_open).to_s)
rescue
"Please check your URL!"
end
end
def frequency_count
#word_array = #doc.css("p").text.split(" ")
#occurance = Hash.new(0)
#word_array.each {|x| #occurance[x.downcase] += 1 }
#occurance.each {|x,y|
if y > 5
puts "#{x} : #{y} times"
end
}
end
end
And I'm trying to access that script's class in a rails controller.
class UrlsController < ApplicationController
def index
#url_to_check = Abc.new("http://ecodehut.com/linux")
end
end
Everything is fine so far but when I call this variable in index.html.erb <%= #url_to_check.frequency_count %> output is this:
{"it’s"=>1, "like"=>1, "asking"=>1, "“should"=>1, "i"=>5, "go"=>3, "to"=>14, "school?”"=>1, "and"=>8, "“would"=>1, "get"=>1, "a"=>3, "job"=>1, "if"=>2, "school?”.list"=>1, "of"=>1, "advantages"=>1, "is"=>5, "never"=>1, "ending"=>1, "elaborating"=>1, "each"=>1, "throw"=>1, "your"=>2, "mouse"=>1, "away"=>1, "this"=>3, "time."=>1, "keyboard"=>1, "all"=>1, "need"=>1, "mozart."=>1, "navigate..."=>1, "before"=>2, "we"=>1, "begin"=>1, "with"=>3, "configuration"=>1, "here"=>1, "download"=>1, "install"=>2, "system."=>1, "after"=>1, "come"=>1, "back"=>1, "continue."=>1}
But my expected output is this:
to : 14 times
and : 8 times
you : 9 times
the : 6 times
I'm not getting why rails printing everything inside the hash instead of the key values with values bigger than 5 like mentioned in the frequency_count method.
P.S: Abc.rb script results fine and dandy when ran in terminal using ruby Abc.rb
Plese change this and try again
def frequency_count
#word_array = #doc.css("p").text.split(" ")
#occurance = Hash.new(0)
#word_array.each {|x| #occurance[x.downcase] += 1 }
#occurance.select {|x, y| y> 5}
end
The reason is the last line of your method is
#occurance.each {|x,y|
if y > 5
puts "#{x} : #{y} times"
end
}
Just iterate all key and values inside #occurance variable but not sort based on the count. So you are getting all key values in the views instead which has count more than 5.
When you do #occurance.select {|x, y| y> 5}, which filter your hash and gives you the desired values which count is more than 5. Now you can just loop it and print inside views.
Hope you understand.
Update
In your index.html.erb put this code, where you would like to print hash details
<% #occurance.each do |key, value| %>
<span><%= "#{key}: #{value}" %></span><br />
<% end %>

ActiveRecord query alias field name output in jBuilder

Hi I am new to ruby on rails development. This is my controller function query
def index
#questions = Question.order('questions.created_at DESC').joins('left join favourites on questions.id=favourites.question_id and favourites.user_id='+current_user_id.to_s).includes(:user).select('CASE WHEN favourites.user_id='+current_user_id.to_s+' THEN 1 ELSE 0 END as favour').references(:favourite).page(params[:page]).per( (ENV['ILM_QUESTIONS_PER_PAGE'] || 15).to_i )
end
From this query i dont know how to get the value for "favour" column in select query.
This is my jbuilder file in views
/index.json.builder
json.number_of_items_per_page #questions.length
json.total_number_of_pages #questions.total_pages
json.user_favour #questions.favour
json.questions do
json.array! #questions do |question|
json.partial! 'api/v1/questions/question', question: question,include_comments: false
end
end
/_question.json.builder
json.id question.id
json.content question.content
json.created_at question.created_at
json.image_url question.image.url
when i put #questions.favour in index.json.builder
i got this error
undefined method `favour' for #<Question::ActiveRecord_Relation:0x0000000c39b5f0>
Please Advice me on this issue
Thanks in Advance.

Do I always need to add 'if something' in order to avoid 'nil' error?

Do I always need to add if #user in this?
In Pattern 1, it doesn't have if #user so it returns 'nil' error when the user was deleted.
In Pattern 2, it won't return 'nil' error but it's too anoying to add this every single line of these things:(
Isn't there any smart way to solve this kind of 'nil' error?
and I just want to display "[Not Found User]" when the user was deleted.
view/posts/show.html.erb
#Pattern 1
<%= display_nickname(#user.nickname) %>
#Pattern 2
<%= display_nickname(#user.nickname) if #user %>
application_helper.rb
def display_nickname(nickname)
if !nickname.nil?
return nickname
end
"[Not Found User]"
end
In many, but not all, cases you can use the "try" method from ActiveSupport.
foo = Foo.find(1)
foo.bar.try(:some_method)
In the example if bar is nil, some_method will also return nil.
So you could do:
#user.try(:nickname)
You can write your helper like that:
def display_nickname(user)
user.try(:nickname) || "[Not Found User]"
end
what about
def display_nickname(user)
"#{user.try(:nickname)}"
end
or
def display_nickname(user)
user ? user.nickname : ''
end
both will print '' if the user is nil, i'd chose the second

HTML escaped in Rails 3

I have a method call in my view like this
<%= Navigation.with(params) do |menu|
if current_user && current_user.can_verify?
menu.item("Listings", manage_listings_path())
menu.item("Listing changes", needing_change_approval_manage_listings_path())
menu.item("Flagged Items", flagged_manage_listings_path())
menu.item("Transfers", manage_listing_transfers_path())
menu.item("Reviews", manage_listing_reviews_path())
end
if current_user && current_user.admin?
menu.item("Log", manage_verifications_path())
menu.item("Indexer Compensations", manage_compensations_path())
menu.item("Users", manage_users_path())
end
end%>
that splits out the below string
"<li>Listings</li> <li>Listing changes</li> <li>Flagged Items</li> <li>Transfers</li> <li>Reviews</li> <li>Log</li> <li>Indexer Compensations</li> <li>Users</li>"
I just get this string in my page. I wanted them to be menus nicely styled by CSS. I am just getting the above raw text in my page. How do I convert this string to be treated as HTML by the browser.
Please help
Here is the navigation class
class NavigationMenu < ActionView::Base
def initialize(params)
#params = params
end
def item(title, path, options={})
#items ||= Array.new
unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
end
#items << content_tag(:li, link_to(title,path, :class => (#params[:controller] == route[:controller] && #params[:action] == route[:action])? 'active' : nil))
end
def output
return '' if #items.blank?
content_tag(:ul, #items.join("\n"), :id => 'navigation')
end
end
class Navigation
def self.with(params, &block)
menu = NavigationMenu.new(params)
yield menu
menu.output
end
end
You have to add a call to the raw method:
<%= raw ... %>
This is necessary, because in Rails 3 every string is escaped by default, unless you use the raw method.
It's like an inverse of the h method in Rails 2, where every string is unescaped by default, unless you use the h method.
Example:
This code in Rails 2...
<%= h "String which must be escaped" %>
<%= "String which must be output raw %>
... must be this in Rails 3:
<%= "String which must be escaped" %>
<%= raw "String which must be output raw %>
(Although an additional call to h doesn't do any harm in Rails 3)
You need to append .html_safe to the string - this will stop rails from escaping it when it's time to output text. Probably best to put it in the item method that you call repeatedly.
I recently wrote an article regarding XSS protection in Rails 3 when upgrading from Rails 2:
http://developer.uservoice.com/entries/upgrading-to-rails-3-printing-escaped-strings
The idea is to hook code to printing HTML so that we can determine when we are actually printing something we don't want to:
module ActionView
module Helpers
module TextHelper
def simple_format_with_double_escape_reporting(*args)
HtmlDoubleEscapeReporter.assert_sane(simple_format_without_double_escape_reporting(*args))
end
alias_method_chain :simple_format, :double_escape_reporting
end
module TagHelper
private
def content_tag_string_with_double_escape_reporting(*args)
HtmlDoubleEscapeReporter.assert_sane(content_tag_string_without_double_escape_reporting(*args))
end
alias_method_chain :content_tag_string, :double_escape_reporting
end
module UrlHelper
def link_to_with_double_escape_reporting(*args, &block)
HtmlDoubleEscapeReporter.assert_sane(link_to_without_double_escape_reporting(*args, &block))
end
alias_method_chain :link_to, :double_escape_reporting
end
end
end
Method HtmlDoubleEscapeReporter.assert_sane can be written, for example, like this:
class HtmlDoubleEscapeReporter
def self.assert_sane(str)
if (str.match(/<[a-z]/) || str.match(/&(quot|rarr|larr|amp|#)/)) &&
!str.match(/looks something you do not want to print/
send_problem_report('#{str}' looks something you do not want to print")
end
return str
end
end
Here, 'looks something you do not want to print' is used to prevent the possibility of infinite loops. The line send_problem_report('#{str}' looks something you do not want to print") can be replaced with a call to "debugger" (from ruby-debug gem) so that you are able to check the backtrace and see where the problem is coming from.
Here is the new class. At last... I got that bug.
class NavigationMenu < ActionView::Base
def initialize(params)
#params = params
end
def item(title, path, options={})
#items ||= Array.new
unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
end
#items << content_tag(:li, link_to(title,path, :class => (#params[:controller] == route[:controller] && #params[:action] == route[:action])? 'active' : nil))
end
def output
#items = #items.join("\n").html_safe
return '' if #items.blank?
content_tag(:ul, #items, :id => 'navigation')
end
end
class Navigation
def self.with(params, &block)
menu = NavigationMenu.new(params)
yield menu
menu.output
end
end

Resources