I am parsing XML returned from the Google contacts API, using XPath in Nokogiri.
def getcontact
doc = Nokogiri::XML.parse(open(url))
doc.xpath('//xmlns:feed/xmlns:entry[xmlns:title[node()]]')
end
My controller is:
def index
#mycontacts = getcontact.to_a.paginate(:page => params[:page], :per_page => 30)
end
My view is:
<% #mycontacts.each do |c| %>
<p> Name: <%= c.xpath('xmlns:title').text %> Email: <%= c.xpath('gd:email/#address').text %></p>
<% end %>
<%= will_paginate #mycontacts %>
I would like to sort by title in alphabetical order and I am wondering how to go about this. I have read that I can use sort_by, but how do I select the title from the array?
The following should work
#mycontacts.sort!{|a, b| a.xpath('xmlns:title').text <=> b.xpath('xmlns:title').text}
The block tells it to do the comparison based on the .xpath('xmlns:title').text for each object.
Related
I have this simple search function:
class SearchController < ApplicationController
def index
if params[:search].blank?
redirect_to root_path
else
#results = Post.search(params[:search])
end
end
end
I want to implement the following functionalities but I am struggling to code:
1.How to record each of the input search terms and see whether which search terms are the most searched ones. I thought of using "first_or_create" method...
2.Give I have this title: "Peter Paul Mary", how do I split them and link_to each terms to search the search function
Please advise.
1.I think you can use two-dimensional array containing results of query for each single term.
#maching_posts = Array.new
#terms = params[:search].split
#terms.each do |term|
result = Post.where(title: term)
#maching_post << result
end
Now, you have array '#maching_post' containing results of query for each single term. Row [0] contains result of first term etc.
You can use this array to generate view. Like this:
<% #terms.each_with_index do |term, index| %>
<span>Results of <%= term %></span>
<% #maching_post[index].each do |post| %>
<%= post.title %></br>
<% end %>
<% end %>
2.To get single words from string you can use split() method.
"Peter Paul Mary".split
This method returns array ["Peter", "Paul", "Mary"]
To link each term, use
link_to 'term', controller: :search, action: :index, search: 'term'
You should use this method in loop, like
<% "Peter Paul Mary".split.each do |term| %>
<%= link_to term, controller: :search, action: :index, search: term %>
<% end %>
I have these two inputs:
<%= search_form_for #search, url: search_path, method: :post do |f| %>
<%= f.text_field :thing_false %>
<%= f.text_field :thing_null %>
<% end %>
and when they're both set to "t", I get this query executed:
SQL: SELECT "stuffs".* FROM "stuffs" WHERE (("stuffs"."thing" = 'f' AND "stuffs"."thing" IS NULL))
How do I make it so I get this executed?
SQL: SELECT "stuffs".* FROM "stuffs" WHERE (("stuffs"."thing" = 'f' OR "stuffs"."thing" IS NULL))
The ransack documentation doesn't really address this. This is the closest example that I can find:
>> User.search(:first_name_or_last_name_cont => "Rya").result.to_sql
=> SELECT "users".* FROM "users" WHERE ("users"."first_name" LIKE '%Rya%'
OR "users"."last_name" LIKE '%Rya%')
If you don't want the user to have to select the "any" option, you can make it so that the search always uses "OR" by adding something like this in your controller:
#search = User.search(params[:q])
#search.combinator = "or"
#users = #search.result
You can also create different groupings of search fields and specify the appropriate combination within the grouping. The controller could have something like:
#search = User.search(params[:q])
(0..1).each do |index|
#search.build_grouping unless #search.groupings[index]
#search.groupings[index].combinator = "or"
end
#users = #search.result
And the view could have something like:
<%= search_form_for #search do |f| %>
<% #search.groupings.each.with_index do |grouping,index| %>
<%= f.grouping_fields grouping do |g| %>
<% if index == 0 %>
<%#= fields for first grouping here %>
<% end %>
<% if index == 1 %>
<%#= fields for second grouping here %>
<% end %>
<% end %>
<% end %>
<%= f.submit "Search" %>
<% end %>
The RansackDemo page is a good place to play around with the different search options. There is a Simple Mode and an Advanced Mode. The source code is available on github and the views there give some indication of how to put together the groupings and conditions.
Additional info is also available in RailsCast 370.
throw this under your search_form_for tag. This is assuming that you're using f:
<%= f.combinator_select %>
it'll generate a select with two options. ALL or ANY. ANY will use an OR clause. ALL will use an AND clause.
There's a good number of related questions but their answers haven't helped me. I have a method fetch_all_sections which populates an array with this line:
all_sections << {:id => section.id, :sortlabel => section.sortlabel, :title => section.title, :depth => depth}
In a loop in a view, I would like to easily access the values by their key, like this:
<% fetch_all_sections(#standard).each do |section| %>
<%= section.id %>
<% end %>
This says no method id on section. section[:id] and #{section['id']} have similarly themed errors. I used a hash for ease of retrieval - should I use a different structure?
I'm hoping I don't need .map like section.map { |id| id[:id] } for every value.
EDIT: Here's the context. It's a little loopy (pun intended) but it does what's intended.
# Calls itself for each section recursively to fetch all possible children
def fetch_all_sections(standard, section = nil, depth = 0)
all_sections = []
if section.nil?
rootsections = standard.sections.sorted
if ! rootsections.nil?
rootsections.each_with_index do |section, i|
depth = section.sortlabel.split('.').length - 1
all_sections.push(fetch_all_sections(standard, section, depth))
end
end
else
all_sections << {:id => section.id, :sortlabel => section.sortlabel, :title => section.title, :depth => depth}
section.children.sorted.each do |section|
all_sections | fetch_all_sections(standard, section)
end
end
return all_sections
end
Try with the following:
<% fetch_all_sections(#standard).each do |section| %>
<%= section['id'] %>
<% end %>
If not working, try debugging using these methods:
<% fetch_all_sections(#standard).each do |section| %>
<%= section.inspect %>
<%= section.class %>
<% end %>
As the Question author said, this fixed:
all_sections << fetch_all_sections(standard, section, depth).first
And tell us the output of the inspect
In my rails application I wanted to use pagination for names. I'm fetching the names from a postgresql table.
def index
#users = User.order("name").paginate(:page=>params[:page],:per_page=>50)
end
Is there a way of alphabetic pagination that has page numbers as a,b,c..........z
Thanks for your help,
Ramya.
Im doing this too in one of my projects. I didnt use a gem for this. Its really easy using Ranges... For example:
<% ('A'..'Z').each do |char| %>
<% if char==params[:char] %>
<%= link_to :action => 'your_action', :char => char, :class => 'selected_char' %>
<% else %>
<%= link_to :action => 'your_action', :char => char %>
<% end %>
<% end %>
Then in the controller Action you select the Objects by the params[:char] given. For example:
#instance_var = ModelName.where("field LIKE ?", "#{params[:char]}%")
this did it for me. You can easy build a partial out of this and use it for many different Models.
How can I show recent added #post and #photos in one list? For example:
post - LAlala (10.10.2011)
photos - [] [] [] [] (1.1.2011)
post - Bbbdsfbs (2.12.2010)
post - Lasdasdf2 (2.10.2009)
#posts = Post.limit(20).order('created_at desc')
#photos = Photo.limit(20).order('created_at desc')
#recent_items = (#posts + #photos).sort_by(&:created_at)
<% #recent_items.each do |item| %>
<% if item.class == "Photo" %>
<%= image_tag item.url %>
<% else %>
<%= item.title %>
<% end %>
<% end %>
Alternatively, use group_by to do it like this:
#recent_items = (#posts + #photos).group_by(&:created_at)
<% #recent_items.each do |date, items| %>
Date: <%= date %>
<% items.each do |item| %>
Show information here.
<% end %>
<% end >
I would move the view logic into a helper if I were you for DRYer code.
It is much better to do this is the database.
I just say this: polymorphism + database views.
Create a database view which contains the columns you need from both Post and Photo, including the column "type" containing a the name of the model (you need it for the polymorphism). Call this view for example "list_items". Then create a model called "ListItem". Then you can use this model like any other, paginate it and whatever you need to do.
ListItem.order("created_at > ?", Date.yesterday).page(params[:page])
And don't forget to configure the polymorphic association
However, all this is much easier to accomplish with the listable gem. Check it out!