I've tested a couple of methods for printing the first 3 instances of my class for a Ruby on Rails application. I've already got the following working :
<%#posts.each do |post| %>
<div class ="post content" >
<h2 class="title"><%=post.title%></h2>
<p class="date"><%= post.created_at.strftime("%B, %d, %Y")%></p>
<p class="body"><%=post.body%></p>
</div>
<% end %>
But I'm trying to do the same thing but only printing the first 3 elements of the #posts variable.
.first(3) and .find(:id) haven't worked and I'm at a loss on how to iterate through the class variables.
Thanks.
If you only need 3 posts and don't require the rest anywhere in your view, then filter them out in your controller and don't query for unused models.
In your controller:
#posts = Post.limit(3) # Post.where(x: 'y').limit(3)
You want to use take.
<% #posts.take(3).each do |post| %>
first works in a similar manner (but it orders by id), and should get the job done as well.
PS: You should consider moving this logic in the controller.
Related
I'm pretty new to ruby/rails so bear with me.
I'm attempting to take the results returned by the JIRA rest API and render them in a view. I can do that pretty easily using the jira-ruby gem. The problem I'm having is grouping the results by a specific object inside the object returned by the API (in this case, a "components" field object inside of a "issue" object). I've attempted to use group_by and chunk for this but I'm basically getting the inverse of what I want. Both methods return the same result.
In my controller I have:
#issues = #jira_client.Issue.all
In my view I have:
<% #issues.chunk {|issue_comp| issue_comp.fields["components"]}.each do |comps, issues| %>
<h2>
<% comps.each do |comp| %>
<%= comp["name"] %>
<% end %>
</h2>
<ul>
<% issues.each do |issue| %>
<li><p><%= link_to issue.key, "http://localhost:2990/jira/browse/#{issue.key}" %> - <%= issue.summary %></p></li>
<% end %>
</ul>
<% end %>
What I end up with is:
CompA CompB
IssueA
CompC CompD
IssueB
CompA CompC CompD
IssueC
etc.
What I want is:
CompA
IssueA
IssueC
CompB
IssueA
CompC
IssueB
IssueC
CompD
IssueB
IssueC
The object returned by the API is a pretty convoluted object (i.e. giant array of hashes inside arrays inside of hashes). So, I have to dig pretty deep to get at the component name.
I get the feeling that this shouldn't be as complicated as it seems but I have a terrible habit of making things more complicated than they need to be. What am I doing wrong here?
EDIT: I created a gist of the full dump that is returned with the above call. Notice the "components" array:
jira-ruby gem dump for all issues
I took a look at the data you're getting back from Jira. This is how it looks to me:
There is an outer array of Jira Issues.
Each issue has an "attrs" hash
Each "attrs" hash contains components.
If this understanding is correct, I think you are attempting to invert that structure so that you can get a complete list of components, then iterate over each of them, and show the Issues that belong to that component.
If that understanding is correct, you have two basic choices:
Check if you can ask Jira for that information (so you don't have to generate it yourself), or
Build your own data structure (in memory on in a local DB as you prefer):
Some sample code for building a useful structure in-memory:
# in a controller, model, or service class (as you wish)
#components = {}
#jira_issues_array.each do |jira_issue| # from your API call
jira_issues[:components].each do |jira_component|
#components[jira_component[:key]] ||= { name: jira_component[:name], issue_keys: [] }
#components[jira_component[:key]][:issue_keys] << jira_issue[:key]
end
end
In your view, you could iterate over #components like this:
# some html.erb file:
<h1>Components and Issues</h1>
<ul>
<% #components.keys.each do |component_key, component| %>
<li><%= component[:name] %>
<ul> <!-- nested -->
<% component[:issue_keys].each do |issue_key| %>
<%= #jira_issues_array.find { |issue| issue[:key] == issue_key }[:name] %>
<% end %>
</ul>
</li>
<% end %>
</ul>
Note: Like a typical lazy programmer, I haven't tried this out, but it's really intended to show how you might go about it. For example, each issue's name is embedded in the attrs section, so you'll need to dig that out a bit.
Finally, if anyone would find this useful, I use this to analyse and reformat JSON.
HTH - any questions or problems, post a comment.
I want to implement a search functionality in my Rails app by using the pg_search gem. I've set up everything like it says in the documentation. Then I've set up a search controller with a show action:
def show
#pg_search_documents = PgSearch.multisearch(search_params)
end
The search itself works but I have a really annoying problem in my view. Whatever I do, it always outputs an array of PgSearch::Document objects. Even when I only write this in my view:
<%= #pg_search_documents.each do |document| %>
<% end %>
I get this (I've shortened it):
[#<PgSearch::Document id: 2, content: "…", searchable_id: 28, searchable_type: "Vessel">, #<PgSearch::Document id: 3, content: "…", searchable_id: 27, searchable_type: "Vessel">]
I know that pg_search sets up a polymorphic association which I've never dealt with before — could that be the problem?
Thanks in advance
<%= #pg_search_documents.each do |document| %>
<% end %>
This is a classic error, one I remember being puzzled over when I first started learning Rails. The mistake is using <%= %> with each. The return value of each is the array that you're iterating over (in this case, #pg_search_documents), and by using <%=, you're telling Rails to create a string from that array and insert it into your view. That generally isn't what you want: you want the view to be generated by the code inside the block you're passing to each.
Use <% #pg_search_documents.each do |document| %> instead (omitting the =) and you'll avoid the dump of the array's content.
You may also need to use .searchable as #blelump suggests, but I wanted to answer the other half of your question, as it's a common pitfall.
To get back to the original source model, searchable call is needed on these search result records, e.g:
<% #pg_search_documents.each do |document| %>
<%= document.searchable %>
<% end %>
You can also switch back to the source model within your controller, e.g:
#pg_search_documents = PgSearch.multisearch(search_params).collect(&:searchable)
Then, the #pg_search_documents will contain Vessel elements.
I'm trying to list all records from the database in the main page.
Model and controllers were both created properly (I suspect) since using the following code and pointing to proper address (http://localhost:3000/subdomainw1s) lists all the records:
in /app/views/subdomainw1s/index.html.erb:
<h1>subdomain word 1</h1>
<ol class="subdomainw1">
<% #subdomainw1s.each do |sdw1| %>
<li>
<%= sdw1.blognamew1 %>
</li>
<% end %>
</ol>
However, attempting to past the same code in /app/views/home/index.html.erb results in an error message ("undefined method `each' for nil:NilClass") complaining about:
<% #subdomainw1s.each do |sdw1| %>
Clearly, rails doesn't know what to do with this model under the home page.. no?
Any advice would be great.
there is at least two more "codeless" options
convert it to (empty) array
..#subdomainw1s.to_a.each do |sdw1|..
or use method try
..#subdomainw1s.try(:each) do |sdw1|..
copy the code to collect the subdomains from 'index' in subdomains controller to 'index' in home controller.
Contacts each have a first_name and last_name. In my index for contacts, I display a list default_scoped by last_name in ASC order. This works OK, but I'm looking to make it better.
I want to create an organized list in the index that groups contacts by the first letter of their last name, and I'm sort of stuck on how to get this done. The result would look like:
<div class="contacts" id="contact_list_a">
<h2>A</h2>
<div class="contact">John Abercrombie</div>
<div class="contact">Julie Aloters</div>
</div>
<div class="contacts" id="contact_list_b">
<h2>B</h2>
<div class="contact">Harry Bronson</div>
<div class="contact">Stevie Brussels</div>
</div>
...(continues)
I only see two options so far because of my inexperience:
1) I could create a variable for each letter of the alphabet, and add contacts where appropriate to each. This creates tons of calls to the DB (I'm assuming), and the abundance of variables in my controller doesn't seem elegant at all.
2) I could pull all contacts from my model into a single variable (what I'm doing now), then in my controller create a private method which iterates through the array and assigns new variables accordingly. This still seems inefficient, but looks better to me that #1.
Could you give insight into a better way to do this? I'm using Ruby 1.9.3 and Rails 3.2.8.
Once you've pulled your users into, say users, you can group them with
# creates a hash mapping first letter of last name to array of corresponding users
groups = users.group_by { |user| user.last_name[0].downcase }
In your view you can iterate through the hash as follows:
<% groups.each do |letter, contacts| %>
<div class="contacts" id="contact_list_<%= letter %>">
<h2>letter.upcase</h2>
<% contacts.each do |contact| %>
<div class="contact"><%= contact.full_name %></div>
<% end %>
</div>
<% end %>
I have a posts model... I am trying to display this model on the index page of the webpage.
<% #posts.each do |post| %>
<%= #posts[1].title %>
<%end%>
The problem with the above code is that it display the title 3 times because i have 3 posts. How do i edit this code to make it only display once.
You meant to do this:
<% #posts.each do |post| %>
<%= post.title %>
<%end%>
The each enumerator passes its variables one at a time into a block with the do |variable| syntax. So post is each item in #posts, one after another.
This is a really fundamental concept to Ruby and Rails: without understanding this further you probably won't get very far. I would recommend you go and read Programming Ruby -- a really excellent tutorial and reference to the Ruby programming language -- to understand how blocks and enumerators work.
If you use 'each' it displays all the posts because in your controller you had #posts = Posts.all. This gives all the posts written till now into the #posts instance variable and each enumerator prints all the posts
If you want only the title to be displayed and that too only for the first post, then you can write like this in your view
<%= #posts.first.title %>