How to call a controller method to populate partial on root page? - ruby-on-rails

I've got a controller method:
def latest_blogs
#latest_blogs = BlogEntry.all.order('dato DESC').limit(4)
end
A root html.erb file which acts as my home page:
<div class="body-box">
<div class="body-content">
<%= render :partial => 'blog_list' %>
</div>
</div>
The blog_list partial:
<div class="blog-list">
<%= latest_blogs.each do |blog| %>
<%= render :partial => "blog_preview", locals: {blog: blog} %>
<% end %>
</div>
And the blog_preview partial which is just a stub for now:
<div class="blog-preview">
<%= blog.title %>
</div>
My routes.rb entries:
resources :blog_entries
root :to => 'home#blog_home', :as => 'root'
How can I tell my app when it loads the root page to present latest_blogs? Thanks.

I would start with: this method should not be in the controller. Put it in a model instead
class BlogEntry < ActiveDirectory::Base
def self.latest (n = 4)
all.order('dato desc').limit(n)
end
Then just use it as:
BlogEntry.latest
Note that this method will also be available on relations:
user.blog_entries.latest(1) #=> returns last user blog entry

You can declare the latest_blog as helper method. Please try the following:
class BlogsController < ApplicationController
def latest_blogs
#latest_blogs = BlogEntry.all.order('dato DESC').limit(4)
end
helper_method :latest_blogs
end

Is latest_blogs your actual controller action, or is it just some method you're exposing to the view? If it's just some method you're exposing then you should make it a helper method.
def latest_blogs
#latest_blogs ||= BlogEntry.all.order('dato DESC').limit(4)
end
helper_method :latest_blogs
Note that I changed the = to ||= in here. I think that's better in this case so that if you happen to call the helper multiple times then it won't re-evaluable it repeatedly.
And FYI, you can also clean up your markup code a little bit. Your root html file could do:
<div class="body-box">
<div class="body-content">
<div class="blog-list">
<%= render partial: 'blog_preview', collection: latest_blogs %>
</div>
</div>
</div>
Then _blog_preview.html.erb:
<div class="blog-preview">
<%= blog_preview.title %>
</div>

Related

Displaying search bar query results from an API in Rails

I am trying to create a simple app where you find games from an API via a search bar. I am using the Giant Bomb API gem (https://github.com/games-directory/api-giantbomb). The gem seems to be working since I can call things via the console. However, I am not quite sure how to display results or if there are problems with my search method (likely).
Here is my controller for Games:
class GamesController < ApplicationController
//Display search results
def index
#games = Game.all.order('created_at DESC')
#games = #games.search(params[:query]) if params[:query].present?
end
//Searches through API and redirects to results on index.
def search
#games = GiantBomb::Search.new().query(params[:query]).resources('game').limit(5).fetch
redirect_to index_path
end
private
def game_params
params.require(:game).permit(:name)
end
end
My search bar code on my home page:
<div class="search-font"><h1>Build your Collection</h1></div>
<div class="container">
<div class="row">
<div class="col-md-12">
<%= form_tag search_path class: "row", method: :get do %>
<div class="col-12 col-sm pr-sm-0">
<%= text_field_tag :game,
params[:game],
class: "form-control input-lg",
id: "typed-text" %>
</div>
<div class="input-group-btn ml-3">
<%= submit_tag "Search", class: "btn btn-primary" %>
</div>
<% end %>
</div>
</div>
</div>
And my index.html.erb where it is supposed to spit out the game names.
<ul>
<% #games.each do |game| %>
<li><%= game.name %></li>
<% end %>
</ul>
The search bar redirects but nothing is posted. In my console I can do search.query('Mario') then search.fetch to print out the results, but I am not sure how to use this function in my controller correctly.
[edit] Here are my routes as well.
Rails.application.routes.draw do
devise_for :users
resources :games
root to: 'pages#home'
get '/search', to: 'games#search', as: :search
get '/games', to: 'games#index', as: :index
end
redirect_to creates a new request, you need to use render as in...
render 'index'
That way you can use your #games variable in the view

How to call a method from Application Controller in any given controller test

I have a controller that POSTs a new instance of a model into a database after the user fills out a form. This form is created using an each do that loops over a series of inventory items defined in the Application Controller.
In other words, this is the view code:
<%= form_for #requestrecord, :html=> {:id => 'form'} do |f| %>
<div class="col-xs-12">
<p><b>Items we have available</b></p>
</div>
<% #inventory.each do |category, list| %>
<div class="col-xs-2">
<div class="form-group box">
<h5> <%="#{category}"%> </h5>
<% list.each do |thing| %>
<%= f.check_box(:items, {:multiple => true}, "#{thing}") %>
<%= f.label(:items, "#{thing}") %>
</br>
<% end %>
</div>
</div>
<% end %>
There is a method in the application controller that defines inventory:
def inventory
#inventory = { some hash }
end
And then this method is called in the Requests controller that I'm trying to test:
def create
inventory
#requestrecord = Request.new(request_params)
end
The problem is in my Rspec controller test, I now have to manually define this inventory again like so:
before do
#inventory = { some hash }
end
Instead of doing this, is there a way to call the method from the Application Controller in the before statement? The #inventory is a rather long hash...
Thanks!
You can access your controller in rspec with 'controller', so
before do
#inventory = controller.inventory
end
should do the job!

How to correctly call models in controller

My Chefs Model is linked to my Meals Model through chef_id. I am displaying information about the chef, and would also like to show information about his meals. I have not been able to figure out the correct way to call it in the controller. Any ideas?
chef controller:
def index
#chefs=Chef.paginate(page: params[:page])
#meals = ????? Cant figure out how to call this
end
Index.html.erb
<div class = 'chef'>
<div class = 'row'>
<% #chefs.each do |chef| %>
<%= render chef %>
<% end %>
</div>
</div>
<%= will_paginate %>
_chef partial
<div class = 'span4'>
<div class = 'chef-box'>
<h2><center><%= link_to chef.name, chef %></center></h2>
<h2><center>"<%= chef.description %>"</center></h2>
<h2><center><%= THIS IS WHERE I WANT TO DISPLAY INFORMATION ON MEALS %></center></h2>
</div>
</div>
If you just want to access the #meals, than you can get it just by for an instance of #chef:
#meals = #chef.meals
given that you have defined the association in the Chef class like following:
class Chef < ActiveRecord::Base
has_many :meals
#rest of the code
end
Have a look at Active Record Associations here.
So, Here I am just giving an example of how to use it in views, you may have to correct it:
in _chef partial
<div class = 'span4'>
<div class = 'chef-box'>
<h2><center><%= link_to chef.name, chef %></center></h2>
<h2><center>"<%= chef.description %>"</center></h2>
<% chef.meals.each do |meal| %>
<h2><center><%= meal.information %></center></h2>
<% end %>
</div>
</div>
You will need to call correct attribute of meal in above sample code.
As previously mentioned – first and foremost make sure the relation is set up in your chef model:
class Chef < ActiveRecord::Base
has_many :meals
end
Then you can call any Chef.meals, whether that's in your controller as:
def index
#chef = Chef.paginate(page: params[:page])
#meals = #chef.meals
end
Or just in your view:
<div class = 'span4'>
<div class = 'chef-box'>
<h2><center><%= link_to chef.name, chef %></center></h2>
<h2><center>"<%= chef.description %>"</center></h2>
<h2>Has <%= pluralize(chef.meals.size, 'meal') %></h2>
<% chef.meals.each do |meal| %>
<% meal.name %>
<% end %>
</div>
</div>
Of note – since Chef is a model name, you should be able to render your _chef.html.erb more cleanly with simply:
<div class = 'chef'>
<div class = 'row'>
<%= render #chef %>
</div>
</div>
<%= will_paginate %>
Note that #chef is singular to match your controller, you could also pass it a collection <%= render #chefs %> if that's what's set up in your controller, and it will do render each chef separately.

Passing local variable to partial inside for each loop rails 3

This is my code for rendering the partial (the #parties collection is being generated correctly, I have tested that):
<% #parties.each do |party| %>
<div class="item">
<%= render 'parties/party', :object => party %>
</div>
<% end %>
And this is the code in the partial:
<%= party.name %>
However, I get the following error:
undefined method `name' for nil:NilClass
I'm at my wits end, someone please help :-|
Also, this is the code for the controller to render the view containing the partial (The controller's called default_controller):
def index
#parties = Party.all
end
Is it of any consequence that this isn't the parties_controller?
I've tried something like below and it worked
<%= render :partial => 'party', :object => party %>
and I can access like party.name. the local variable is named after the partial name which is party here.
Note: Im assuming that your both partials are of parties_controller. So this should work.
Update:
Here is what ive tried with again
class PostsController < ApplicationController
#... ...
def index
#posts = Post.all
#comments = Comment.all #<---- Loading comments from PostsController
#... ...
end
end
#views/posts/index.html.erb
<% #comments.each do |comment| %>
<%= render :partial=>"comments/comment", :object=>comment %>
<% end %>
#views/comments/_comment.html.erb
<%= comment.body %>
And its working :)

How can I display a list of child records?

I have a table of accounts and venues where an account can have many venues.
I'm displaying all the accounts as partials on the accounts index page and would like for each one to include the names of the venues linked to them.
Heres what I have:
account partial
<%= link_to free_account do %>
<div class="account_partial">
<span class="account_header"><%= free_account.name %></span> - <span class="free_account_highlight">(<%= free_account.role %>)</span><br>
<%= render :partial => 'venues/account_venue', :collection => #account.venues %>
</div>
<% end %>
account_venue partial
<%= venue.name %>
I'm getting this error:
NoMethodError in Accounts#index
undefined method `venues' for nil:NilClass
Extracted source (around line #12):
12: <%= render :partial => 'venues/account_venue',
:collection => #account.venues %>
Any help would be much appreciated!
edit
accounts_controller
class AccountsController < ApplicationController
load_and_authorize_resource
def index
#accounts = Account.all(:include => :venues)
end
end
accounts index.html.erb
<div id="narrow_container">
<div class="free_accounts_container">
<h2 class="show_orange">Free accounts</h3>
<%= render :partial => 'free_account', :collection => #accounts %>
</div>
<div class="premium_accounts_container">
<h2 class="show_orange">Premium accounts</h3>
<%= render :partial => 'premium_account', :collection => #accounts %><br><br>
</div>
<div class="clearall"></div>
<div class="button">
<%= link_to 'add account', new_account_path %>
</div>
</div>
_free_account.html.erb
<%= link_to free_account do %>
<% if free_account.role == "free" %>
<div class="account_partial">
<span class="account_header"><%= free_account.name %></span> - <span class="free_account_highlight">(<%= free_account.role %>)</span><br>
<div class="owner_details">
<span class="pre_account_highlight">Owners username:</span><span class="account_highlight"><%= free_account.user.username %></span>
<span class="pre_account_highlight">Owners e-mail:</span><span class="account_highlight"><%= free_account.user.email %></span>
</div>
<div class="account_details">
</div>
<%= render :partial => 'venues/account_venue', :collection => #account.venues %>
</div>
<% else %>
<% end %>
<% end %>
update
If I change the partial call to:
<%= render :partial => 'venues/account_venue', :collection => #accounts %>
and the account_venue partial to just read 'test' it loads without error but displays the word test 4 times (theres 4 account records) if I add a new account record it displays the word test 5 times.
You need to set #account to something in your controller, and that model instance should be joined to (or include) the Venues model. Like so:
#account = Account.find(params[:id], :include => :venues)
Edit: I take it you have already set up your Account and Venue models with has_many and belongs_to relationships?
Edit two: I see now that you're trying to access Accounts#index, in which case the code above should be changed to something like (since we're not looking at one specific account):
#accounts = Account.all(:include => :venues)
Edit three: Now that you've posted the controller and partials code as well, a couple of things stand out; When rendering a partial using a collection the resulting object inside the partial derives its name from the partial and not the collection. From the Rails Guides:
"When a partial is called with a pluralized collection, then the
individual instances of the partial have access to the member of the
collection being rendered via a variable named after the partial."
In your partial _account_venue.html.erb you have <%= venue.name %> - this needs to be changed to <%= account_venue.name %>.
Secondly, in _free_account.html.erb, where you call the account_venue partial, you're referring to a collection object named #account - where does this come from? Since the free_account partial is also called with a collection, the object you should be using will be called free_account - indeed you are referencing it by this name earlier in the same partial when you do <%= free_account.name %>. So the render partial call should look like this:
<%= render :partial => 'venues/account_venue', :collection => free_account.venues %>
Hope this helps!
Looks like your not assigning #account to anything. Should this be free_account instead?

Resources