I have a simple method on a Person model like so:
def fullname
[title, forenames, surname].join(" ")
end
Sometimes, the output I get from this is perfect, othertimes I need each part wrapped in a span with a class. I could do this in the method but it sort of feels wrong to be putting spans in the model.
Can anyone offer a nicer solution? How would you get this method to offer both of the following output options:
Title Forenames Surname
<span class"title">Title <span class"forenames">Forenames <span class"surname">Surname
Thanks
Try this:
def fullname(spanned = false)
{
'title': title,
'forenames': forenames,
'surname': surname
}.map { |k,v| spanned ? "<span class='#{k}'>#{v}</span>" : v }.join(' ')
end
puts(fullname(true))
# result: <span class='title'>title</span> <span class='forenames'>forenames</span> <span class='surname'>surname</span>
puts(fullname)
# result: title forenames surname
Related
How to pass the search parameters in the link to print.
I have a method #index controller #TicketsController
def index
#search = current_account.searches.find_by(id: params[:search_id])
#q = policy_scope(Ticket).ransack(params[:q])
if params[:q].blank? && params[:advanced_search].blank? || params[:q]&.to_unsafe_h&.length == 1 && params[:q][:s].present?
#q.add_default_condition('status', 'in', 'open')
session[:last_ticket_search] = nil
else
session[:last_ticket_search] = {q: params[:q]}
if params[:advanced_search].present?
session[:last_ticket_search].merge!(advanced_search: 't', selected_columns: params[:selected_columns])
session[:last_ticket_search].merge!(params[:search_id].present? ? {search_id: params[:search_id]} : {commit: 'Apply'})
end
end
#selected_columns = selected_columns
#tickets = #q.result.select('tickets.*')
.includes(:account, :ticket_responses, :assignee, :tags)
.order('tickets.created_at DESC')
.paginate(page: params[:page], per_page: per_page('tickets'))
end
I need to make a page for printing all objects.
For this I made the link Print in `tickets/index.html.erb
<a class="btn btn-primary print-button" href="<%= tickets_path(variant: :print) %>" target="_blank" title="Print ticket" data-tooltip data-placement="bottom">
<i class="fa fa-print"></i>
</a>
The point is that if you click on it will open the whole list of objects here, all is well. But if I use search, I will generate the list of all objects. I need a list of objects I defined in the search. So how do I pass a search parameter in the controller to generate the print page?
I tried that.
<%= tickets_path(q: params[:q], advanced_search: params[:advanced_search], variant: :print) %>
But the controller does not share parameters and accepts a string.
need: "utf8"=>"✓", "q"=><ActionController::Parameters {"assignee_id_eq"=>"", "status_in"=>"closed", "ticket_type_eq"=>"", "simple_search"=>""}
I get: {"q"=>"assignee_id_eq=&simple_search=&status_in=closed&ticket_type_eq=", "variant"=>"print", "controller"=>"tickets", "action"=>"index"}
Just create an instance variable with your required parameters parsed into a hash which will be available in the view:
def new
#search_params = Rack::Utils.parse_nested_query params[:q]
...
end
and in the view:
<%= tickets_path(q: #search_params[:q], advanced_search: params[:advanced_search], variant: :print) %>
New to Rails API's. I want to have an updating picture displayed in my views. The JSON data I'm pulling from can be found here
My Model
def self.get_api_info
helio_api = "http://www.lmsal.com/hek/her?cosec=2&cmd=search&type=column&event_type=fl,bu&event_starttime=2017-03-01T00:00:00&event_endtime=2017-03-08T00:00:00&event_coordsys=helioprojective&x1=-1200&x2=1200&y1=-1200&y2=1200"
request_to_helio_api = Net::HTTP.get(URI(helio_api))
JSON.parse request_to_helio_api
end
My Controller
def index
#helio_info = HelioApi.get_api_info
end
And my View
<img src="<%= #helio_info["gs_thumburl"] %>" />
The structure of the API you're accessing is
{
"result": [
{ "gs_thumburl": "some_string", ... },
{ "gs_thumburl": "some_string", ... },
{ "gs_thumburl": "some_string", ... }
]
}
So to go from #helio_info to some_string you need to grab the result array #helio_info["result"] and then an element in that array #helio_info["result"][0], and finally grab the url #helio_info["result"][0]["gs_thumburl"]. Ruby said no implicit conversion of String into Integer because you tried to access an array using a string key, and it expects integer keys.
Thanks for the insight Pavan. Here's what I ended up doing:
Model kept the same
Controller
def index
#helio_info = HelioApi.get_api_info['result']
puts "!!!!!!!!!!!!!!*********!!!!!!!!!********!!!!!"
puts #helio_info
end
View
<% #helio_info.each do |info| %>
<% if info['gs_thumburl'] != "" %>
<img src="<%= info['gs_thumburl']%>"/>
<%end%>
I have following HTML code. I want to get the href & title of the product & store them into different variables. I have tried following code.
within("div.product-action") do
#product_url = find("a.href")
end
But that throws an error.
Capybara::ElementNotFound: Unable to find css "a.href"
My HTML code is as follow:
<div class="product-action zoom" ng-class="{ 'logged-out': !user.$isLoggedIn }">
<a href="/g/women/christian-dior/so-real-sunglasses-colorless" title="Christian Dior So Real" Sunglasses-Colorless" ng-click="ProductUtils.cache(result)" class="bottom-action-container quickview-button hover-option" track="{
type: 'product-info',
name: moduleType,
breadcrumbs: result.breadcrumbs || breadcrumbs
}">
<i class="icon-zoom"></i>
</a>
</div>
a.href will select the a elements that have a href class. This is not what you want.
You can access the attributes as a hash after you found the element:
a = find('.product-action a')
href = a[:href]
title = a[:title]
You can find the href and title of given html code with below mentioned code:
within("div.product-action") do
productUrl = find(:css, '.bottom-action-container')[:href]
productTitle = find(:css, '.bottom-action-container')[:title]
end
OR
within("div.product-action") do
productUrl = find('a')[:href]
productTitle = find('a')[:title]
end
Hope this helps :)
I have notes attribute in Product model with text "something, something else".
In views I wanted see:
<div>
<span>Something</span>
<span>Something else</span>
</div>
Also I have working code, but I want refactor with decorator(draper) or maybe use helpers.
%div
- product.notes.split(/,/).each do |e|
%span= e.strip.capitalize
In decorator:
def notes_list
model.notes.split(/,/).each do |e|
h.content_tag(:span, e.strip.capitalize)
end
end
In views:
%div
= product.notes_list
(or analog in helpers:
def notes_list(product)
product.notes.split(/,/).each do |element|
content_tag(:span, element.strip.capitalize)
end
end
call:
%div
= notes_list(product)
)
But this returns
<div>
"
["something", " something else"]
"
</div>
What is wrong?
your notes_list is returning product.notes.split(/,/)
Try
def notes_list(product)
result = product.notes.split(/,/).inject([]) do |result, element|
result << content_tag(:span, element.strip.mb_chars.capitalize)
end
result.join("\n")
end
I've got two small structural issues that I'm not sure how to handle given my relative newbie-ness with RoR.
First issue: In one of my views, I have code that looks like this:
<ul style="list-style-type: circle">
<li><%= #apples.size %> apples</li>
<li><%= #oranges.size %> oranges</li>
<li><%= #bananas.size %> bananas</li>
<li><%= #grapefruits.size %> grapefruits</li>
</ul>
Is it possible to refactor this so that I only need to iterate once over some list of different kinds of fruit, and have the appropriate <li>'s be automatically generated? Edit: I forgot to add that #apples, #oranges, etc., might be nil. Is there an idiomatic way to handle that?
Second issue: In my controller, I have code that looks like this:
#apples = Apple.find(:all)
#apples.each { |apple| apple.do_stuff(:xyz) }
#bananas = Banana.find(:all)
#bananas.each = { |banana| banana.do_stuff(:xyz) }
# ... &c
As you can see, the same operation is invoked many times in exactly the same way. Is there a way to shorten this to something like [Apple.find(:all), ...].each { |fruit| ... } and have that work instead?
Thanks very much for your help!
I'd do this in a helper
def fruit_size(fruit)
list = #fruits[fruit]
return if list.empty?
content_tag(:li, "#{list.size} #{fruit}")
end
And this in the view:
<% ["apples", "oranges", "bananas", .....].each do |fruit| %>
<%= fruit_size(fruit)
<% end %>
In your controller:
#fruits = {}
["apples", "oranges", "bananas", ......].each do |fruit|
#fruits[fruit] = fruit.classify.constantize.find(:all).each {|record|
record.whatever_here
end
end
It makes sense to store all the items in a hash, #fruits, so that you don't have to use instance_variable_get and stuff.
Perhaps you also want to define that array somewhere, so that you don't have to repeat it in the controller and in the view. Let's pretend that you have a fruit model.
class Fruit < ActiveRecord::Base
FRUITS = ["apples", "oranges", "bananas", ....]
end
Then, use Fruit::FRUITS in the view and controller.
For the first part:
#li = ''
[#apples, #oranges, #bananas, #grapefruit].each{|fruit|
#li << "<li>#{fruit.size}</li>"}
<ul style="list-style-type: circle">
<%=#li%>
</ul>
You can actually do it pretty simply.
In your controller:
def whatever
#fruits = {
:apples => Apple.find(:all).each{ |a| a.do_stuff(:xyz) },
:bananas => Banana.find(:all).each{ |a| a.do_stuff(:xyz) } # ...
}
end
In your view:
<% #fruits.each |k, v| %>
<li><%= v.nil? ? 0 : v.size %> <%= k.to_s %></li>
<% end %>
Although you might want to consider whether do_stuff is something that could be done via a more complex finder, or by named scope.