Without an action in controller how does rails execute the view? - ruby-on-rails

I just started learning rails. I have a doubt in the following section.
Controller:
book_controller.rb
class BookController < ApplicationController
end
View:
list.html.erb
<% if #books.blank? %>
<p>There are not any books currently in the system.</p>
<% else %>
<p>These are the current books in our system</p>
<ul id="books">
<% #books.each do |c| %>
<li><%= link_to c.title, {:action => 'show', :id => c.id} -%></li>
<% end %>
</ul>
<% end %>
Router:
get 'list' => 'book#list'
When I goto localhost:3000/list, it displays the content of list.html.erb. How does that happen when I don't have an list action in Controller? How is my understanding wrong?

If the #books is defined in the book controller there is no trouble executing this code since the list.html.erb is already define inside the books folder and the route is set as
get 'list' => 'book#list'

Ruby MVC structure is integrated such that when you create a variable #varibale it is already available at view.

Related

How to use one layout by two different actions in rails 4

I'm building a micropost rails app where users can create posts, I created a route and an action to display posts that belong to the signed-in user, happens that the general index layout for posts is exactly the same as the "myposts" layout so instead of duplicating code I would like to use just one layout with different parameters.
This is what I have until now:
routes.rb
resources :posts
get '/myposts', to: 'posts#my_posts', as: 'myposts'
posts_controller.rb
def index
#posts = Post.all
end
def my_posts
#myposts= Post.where(user_id: current_user.id)
end
index.html.erb
<% #posts.each do |post| %>
<div>
<h1><%= link_to post.title, post %></h1>
<%= link_to image_tag(post.meme_url(:thumb)), post, :target => "_blank" %>
</div>
<% end %>
my_posts.html.erb
<% #myposts.each do |post| %>
<div>
<h1><%= link_to post.title, post %></h1>
<%= link_to image_tag(post.meme_url(:thumb)), post, :target => "_blank" %>
</div>
<% end %>
Thanks in advance!
You can use 'render' on 'my_posts' action - http://guides.rubyonrails.org/layouts_and_rendering.html#using-render
Add before 'end' in my_posts action:
render :index

How to Display Refinery Admin Pages sitemap on front end Rails

I want to display Refinery Admin pages hierarchy on front end as a site map to my users,
i'm new to RefineryCMS, can u please point to right direction? I have attached the image, that image comes under refinery/Admin section i want to add it on my site for visitors too, u can imagine i have a controller site_maps and action index and i want to display that site map under app/views/site_maps/index.html.erb page. Hope it make sense. Thanks.
I implemented this by performing following steps.
1: In controller (mine is site_maps.rb)
class SiteMapsController < ApplicationController
def index
#pages = Refinery::Page.where(parent_id:nil)
end
end
2nd: in index.html.erb View
<div class = "row">
<%#pages.live.each do |page|%>
<% if page.show_in_menu%>
<ul>
<li>
<%= link_to (page_title_with_translations page), refinery.url_for((page.url_marketable)) %>
<%if page.children.any?%>
<%= render :partial => 'shared/page', locals: {:page_children => page} %>
<%-end %>
</li>
</ul>
<%end%>
<%end%>
</div>
3rd: in _page.html.erb
<% page_children.children.live.each do |children_page|%>
<ul>
<li>
<%= link_to (page_title_with_translations children_page), refinery.url_for((children_page.url_marketable)) %>
<%if children_page.children.any?%>
<%= render :partial => 'shared/page', locals: {:page_children => children_page} %>
<%-end %>
</li>
</ul>
<%end%>
NOTE: Without This refinery function refinery.url_for your links might be detected as spider's search and will get wrong!!
Do you mean as the homepage?
then:
mount Refinery::Core::Engine, :at => '/'

Incorrect partial being rendered in my rails app

I've been stumped as to why my rails app is rendering the wrong partial. I have two partials, each related to a different controller (invitations and guests controllers). One partial lists the number of invitations sent out to users and the second partial lists those users who have confirmed their invitation. In addition, the second partial also allows one to see a simple profile of the confirmed guests.
What is happening is that when I visit the link related to the guests controller events/1/guests/, I expect to see the partial related to the guest profile. Instead, the partial related to the invitations controller is rendered. Both the invitations and guests controllers are nested resources of events.
Below is the code that I have been working with. Thanks!
Routes
resources :events, only: [:new, :show, :create] do
resources :invitations, only: [:new, :create, :show]
resources :guests, only: :show
end
match '/events/:id/guests', to: 'guests#show'
Guests controller
def show
#event = Event.find_by_id(params[:id])
#guestlist = #event.invitations.where(accepted: true)
end
views/guests/show.html.erb
<% provide(:title, #event.eventname + " Guest List") %>
<h1> Guest list for <%= #event.eventname %> </h1>
<% if #event.invitations.any? %>
<%= render #guestlist %>
<% end %>
views/guests/_guestlist.html.erb
<li>
<%= guestlist.name %> | <%= guestlist.occupation %> |
<%= guestlist.interests %>
</li>
Instead, the following partial is being rendered:
views/invitations/_invitation.html.erb
<li>
<%= invitation.name %> | <%= invitation.email %> |
<% if invitation.accepted == true %> <%= "Confirmed" %> <% else %> <%= "Pending" %> <% end %>
</li>
The following snippet depicts the correct way to invoke your partial:
# app/views/guests/show.html.erb
<%= render :partial => 'guests/guestlist', :locals => {:guestlist => #guestlist} %>
Since you need access to the #guestlist instance variable in your partial, you'll need to pass it as a local. Then, in your partial, guestlist will be available as a local variable.
Then, within your partial, you'll need to iterate over the members of your guestlist:
# app/views/guests/_guestlist.html.erb
<% guestlist.each do |guest| %>
<li>
<%= guest.name %> | <%= guest.occupation %> | <%= guest.interests %>
</li>
<% end %>
UPDATE:
The reason the OP's original invocation of the partial rendered the invitation partial is that #guestlist is actually comprised of Invitation objects, and thus, the <%= render #guestlist %> method was actually looking for a partial named invitation. From the canonical Rails guides:
There is also a shorthand for this. Assuming #products is a collection
of product instances, you can simply write this in the index.html.erb
to produce the same result:
<h1>Products</h1>
<%= render #products %>
Rails determines the name of the partial to use by looking at the
model name in the collection.
Because of this, you need to explicitly declare the name of the partial you want to use, otherwise ActionView will use the invitation partial by default.
If #guestlist is an object of type Guest, then it would by default render _guest.html.erb.
So, you can try This
<%= render 'guestlist' %>
Variable #guestlist would be automatically available in the partial, so no need to pass it in locals.
Hope this works.
In your show action, you have defined
#guestlist = #event.invitations.where(accepted: true) # it returns array of obejects or records
Now, Please have a try with the following code
views/guests/show.html.erb
<% unless #guestlist.blank? %>
<%= render "/guests/guestlist" %>
<% end %>
views/guests/_guestlist.html.erb
<% #guestlist.each do |guestlist| %>
<li>
<%= guestlist.name %> | <%= guestlist.occupation %> |
<%= guestlist.interests %>
</li>
<% end %>

rails trouble with nested resources and routes

I've been using the
to_param
username
end
in my user model so that I can access users by /user/username (instead of ID)
I'm trying to make links to user listings (listings is a nested resource) with:
#listings represent a query on the Listing model
<% #listings.each do |listing| %>
<%= link_to 'Show', user_listings_url(listing.user_id, listing) %>
<% end %>
But its giving me the user_id instead and I tried querying the listing.user_id into the users model but it just returned and object and I can't get the simple user/username/listing path to work :/ Any help? Should I not be using to_param?
try this:
<% #listings.each do |listing| %>
<%= link_to 'Show', user_listings_url([listing.user, listing]) %>
<% end %>
this will link to /user/username/listings/listing_id

Rails: Link to partials?

At the moment I try to do following:
I created several partials (i.e. _show_signature.html.erb) for my user.
Now I want to show them on clicking a link.
In my user controller, I created a new action:
def show_signature
#is_on_show_signature = true
end
def show_information
#is_on_show_information = true
end
on my user show.html.erb i coded this:
<% if #is_on_show_information %>
<%= render :partial => 'show_information' %>
<% elsif #is_on_show_signature %>
<%= render :partial => 'show_signature' %>
<% end %>
and in my "navigationbar" i wrote:
<ul>
<li class="profile-tab">
<%= link_to 'Information', show_information_path %>
</li>
<li class="profile-tab">
<%= link_to 'Signature', show_signature_path %>
</li>
</ul>
In my routes.rb I wrote:
map.show_information '/user-information', :controller => 'user', :action => 'show_information'
map.show_signature '/user-signature', :controller => 'user', :action => 'show_signature'
now my problem:
clicking on my "information" link will redirect me to http://localhost:3000/user-information (cause I told him this path in routes.rb - I think) and I get an error:
uninitialized constant UserController
But that's not what I want... My user show path is something like:
http://localhost:3000/users/2-loginname
(by coding
def to_param
"#{id}-#{login.downcase.gsub(/[^[:alnum:]]/,'-')}".gsub(/-{2,}/,'-')
end
in my user model)
I want to link to somethink like http://localhost:3000/users/2-test/user-information.
Any ideas how it will work? Any ideas why I get this error?
As far as Rails conventions go, the model itself is singular (User) but the table (users) and controller (UsersController) are both pluralized. This can cause a significant amount of confusion at first, and even after years of working with Rails I still make the mistake of trying things like 'user = Users.first' which is, of course, not valid, as often you get to thinking about table names instead of class names.
Also, for toggling the display of elements on a page, you probably want to use the link_to_remote method which uses AJAX for updates instead of a page refresh. If you're okay with a full page refresh, those actions will need to redirect_to something, such as the page referrer, or you will get a blank page or error since the page template does not exist.
Typically what you do is:
<ul>
<li class="profile-tab">
<%= link_to_remote 'Information', show_information_path %>
</li>
<li class="profile-tab">
<%= link_to_remote 'Signature', show_signature_path %>
</li>
</ul>
Then each action is as you have specified, however, the page template show_information.rjs would look like:
page.replace_html('extra_information', :partial => 'show_information')
Keep in mind you will need to have a placeholder to receive the partial contents, so simply wrap your optional sections in an element with a specific ID:
<div id="extra_information">
<% if #is_on_show_information %>
<%= render :partial => 'show_information' %>
<% elsif #is_on_show_signature %>
<%= render :partial => 'show_signature' %>
<% end %>
</div>

Resources