Problem with linking in Rails application - ruby-on-rails

I am new to rails and I am creating a basic blog application.
When I have created a post it has an author. If you locate the author it displays a list of posts that have been created by that author, however when you select the post it is not linking to the post and is instead giving me the following error:
ActiveRecord::RecordNotFound in PagesController#show
Couldn't find Page with ID=2
app/controllers/pages_controller.rb:8:in `show'
{"id"=>"2"}
My code in the Pages Controller is as follows:
def show #Show action
#page = Page.find(params[:id])
It looks as though when I select the link from the author menu it is not locating the correct page ID as it is routing to 2, 3, 4 etc, when the URL of the post is more like 28, 29, 30. If I locate the post in directly from the index menu the link to the post works fine.
Any help will be appreciated.

<% #author.pages.each do |p| %>
<%= link_to p.title, [[p.url]] %>
<% end %>
replace "[[p.url]]" with how you have your urls set up maybe
{:controller => 'pages', :action => 'show', :id => p.id}
Then format for your liking.

I suspect you are passing a different object to the page_path parameter of the link to method on your authors page, below is an example of some erb for displaying a list of pages for an author and linking to them:
<ul>
<% #author.pages.each do |page| %>
<li><%= link_to page.title, page_path(page) %></li>
<% end %>
</ul>

Related

Show page failing to pass seed data along (rails)

I have a seed database that renders Admin user information and links to individual member profile pages. The database renders images and data fine in the main page, but comes up nil <p>, with id </p> *== $0* when I try to call the individual objects on the show page.
routes.rb:
get '/team', to: 'pages#team'
get '/team/:id', to: 'pages#show', as: 'agent'
pages_controller.rb:
def team
#admins = Admin.where(role: :staff)
end
def show
#admin = Admin.find(params[:id])
end
views/pages/team.html.erb:
<%= link_to agent_path(agent.id), class:"team-link" do %>
.....
<% end %> (all working, routes stable)
views/pages/show.html.erb:
<p><% #admin.name %>, with id <% #admin.id %></p>
#rendering == $0
Where's the data connection breaking down? I've been working at this for a day or so now and this is a fairly solid wall for me.
Ah, your ERB statements are a bit off. You need to use the <%= %> format for the output of your ruby code to be shown (note the =).
So <% #admin.name %> should be <%= #admin.name %>, etc.

link_to blog path from blog_id in Post table

On my index page, I'm listing all the posts from all the blogs. How would I link_to from a post that has a blog_id to that actual blog.
I could easily in a controller do #blog = Blog.find(#posts.blog_id) if it were just one blog, but since it's not and I already have the blog_id for the post blog, I feel there has to be a way to do something like:
<% #posts.each do |f| %>
<%= f.title %>
#<%= link_to "Blog", go to the Blog using f.blog_id somehow? %>
<% end %>
The answer was given in a comment from "BroiStatse" and I thought I'd give the answer to it since he answered it in the comments section.
Basically had to do this simple line:
link_to 'Blog', blog_path(f.blog_id)

Nil id causing routing problems

I have 3 models: posts, comments and questions. Comments belong to posts and questions belong to comments. I'm trying to link from my posts show page to my questions show page. The posts show page is calling a partial _comments which the link is in. The problem is that the link goes to the questions index instead of the questions show because the question.id is nil. The URL looks like this:
/comments/19/questions/
The routes:
comment_question GET /comments/:comment_id/questions/:id(.:format) questions#show
comment_questions GET /comments/:comment_id/questions(.:format) questions#index
The link in the _comments partial:
<%= div_for(comment) do %>
<% comment.questions.select(:title).order('created_at desc').limit(3).each do |question| %>
<%= link_to question.title, comment_question_path(comment, question) %>
<% end %>
<% end %>
The partial is called in the posts show page with this:
<%= render :partial => #post.comments %>
I changed the link to this:
<%= url_for :controller => 'questions', :action => 'show', :comment_id => comment.id, :id => question.id %>
but got this error:
No route matches {:action=>"show", :controller=>"questions", :id=>nil, :comment_id=>20}
Thanks for the help!
Your question isn't nil, the question object just has no ID attached to it.
<% comment.questions.select(:title).order('created_at desc').limit(3).each do |question| %>
That line will build a query similar to the following (ignoring joins with comments):
SELECT title FROM questions
When you pass that to comment_question_path(comment, question) it just reads the attribute, it doesn't try to fetch it from the database. The ID in that question object will be nil because you haven't queried for it, hence why it's building a link with a nil question ID.
If you really want to use select, use comment.questions.select([:id, :title]) instead.
If you don't care about using select, just use comment.questions instead.
More info on select: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields

Strange routing in rails render partials

I'm new to rails and thought I had finally figured out some of this routing stuff, but have been going in circles with this bit all day.
I was following a tutorial about building a twitter like service, and I've got the basics working from the tutorial, but with Mongo instead of mySql.
I've got 3 types of pages.
The home page which is showing all the posts ordered by date
The user page which is showing the posts from a specific user
The posts page which is showing posts from a users friends.
So for each page, I've done the following
1) created a method in the corresponding controller to get the correct posts
2) created a _posts.html.erb page with the display parameters, which are slightly different on each page
3) referenced the partial in the index.html.erb page for each view.
The controller entries look like this
def index
#posts = Post.all(:order => 'created_at DESC')
end
or
def posts
#posts = Post.all(:conditions => {'user_id' => params[:id]}, :order => 'created_at DESC')
end
and the partials are
<%= render :partial => #posts %>
In each view is a _posts.html.erb file, and each is slightly different
home/_posts.html.erb looks like this
<%= div_for post do %>
Posted <%= time_ago_in_words(post.created_at) %> ago
Posted By <%= post.user_id %>
<%= post.text %>
<% end %>
while posts/_post.html.erb looks like this
<%= div_for post do %>
Posted By <%= post.user_id %>
<%= post.text %>
<% if post.created_at > 52.hours.since %>
<%= distance_of_time_in_words_to_now(post.created_at) %>
<% else %>
<%= post.created_at.strftime("%c") %>
<% end %>
<% end %>
Now the strange part is that on all the pages index.html.erb, users/show.html.erb, posts/index.html.erb, the partial that is being displayed is the posts/_post.html.erb. The others are being completely ignored.
my understanding was that render :partial would take the #posts and render _posts.html.erb from the current view. But this isn't happening, as only the posts/_post.html.erb is being rendered from all views.
I've looked in the routes.rb file, but don't have anything in there that would cause this problem.
Can anybody tell me why I am not displaying the proper partials?
-----------Edited --------------------------------
The directory structure for views is as follows
views
- home
-_post.html.erb
-index.htlm.erb
- layouts
- posts
-_post.html.erb
-index.html.erb
-posts.html.erb
- sessions
- users
-_post.html.erb
-new.html.erb
-show.html.erb
I hope that helps.
"post", :collection => #posts%>
maybe rails automatically defines path to the partial when you pass only collection
You're passing the collection as the argument that rails is expecting to be the name of the partial. Your call to render should look like this
<%= render partial: "post", collection: #posts %>
This will render app/views/posts/_post.html.erb, passing the local variable post to the partial.
Additionally, (is sometimes handy) there's an iteration object that is made available to this view, partial_name_iteration, that has information about the total size of the #posts collection, and the index of the current object.

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