i'm having a no route matches error after a render :partial
<% unless #user.uploads.empty? %>
<% #user.uploads.each do |u| %>
<tr>
<td><%= link_to u.filename, u.filename %></td>
it gives me the right filename like http://localhost:3000/DSC00082.JPG.
i haven't added anything to my routes.
for being new to rails, please excuse my (hopefully) easy question.
to add a question: is it right for the corresponding database entry to be just the filename?
after changing above code to
<% unless #user.uploads.empty? %>
<% #user.uploads.each do |uploads| %>
<tr>
<td><%= link_to (uploads.filename, uploads) %></td>
and adding map.rescources :upload,
a "No action responded to show" message was generated. in the adress bar, my browser shows the id of the regarding dataset.
Greetings,
devyn
If u is a subclass of ActiveRecord::Base, your link_to has to be like this:
<%= link_to u.filename, u %>
The same Rails would detect that u is an object with controller, and it will convert it to a REST valid URL (and redirect you to the show action).
If this isn't your scenario, please tell me.
[EDIT]
If you know how Rails work, skip this paragraph:
With map.resources :upload you are telling rails that you have a resource called Upload that has a UploadController, and generates routes for 5 actions: new/create, index, show, edit/update and destroy. Each action needs a method in the controller(See the ClientsController example in Rails Guides).
"No action responded to show" raises when you don't have UploadsController#show. An example of this method:
def show
#upload = Upload.find(params[:id])
respond_to do |format|
format.html
format.xml {render :xml => #upload}
end
end
This method render a the file views/uploads/show (be sure of create it).
Related
I am a beginner in ROR development. I have navigation and I want search box on every page and when I enter some keyword, it should do like query across table's field. I tried using some online tutorials but could not do it.
My table name : tutorials
here is my search form on navigation bar
<li><%= link_to 'Login', :controller => 'access', :action => 'login' %></li>
<li><%= link_to 'Sign Up', :controller => 'users', :action => 'new' %></li>
<li><%= link_to 'Logout', :controller => 'access', :action => 'logout' %></li>
<div align="right">
<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
</div>
Here is my controller
class SearchController < ApplicationController
def show
#tutorial = Tutorial.find(params[:q])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #tutorial }
end
end
end
Here is my model
class Search < ActiveRecord::Base
def #tutorial.search(search)
if search
find(:all, :conditions => ['tutorial_name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
end
I am not sure how to do this. Please help
It's often true that a bad name indicates wrong thinking. I believe your name Search for the model is in this category. It should probably be called Tutorial, no? Search is something you do to a model, not the model itself.
If this guesswork is correct and the model is now called Tutorial and it has a field called name that is a string, then your model will be
class Tutorial < ActiveRecord::Base
def self.search(pattern)
if pattern.blank? # blank? covers both nil and empty string
all
else
where('name LIKE ?', "%#{pattern}%")
end
end
end
This makes the model "smart" on how to search through tutorial names: Tutorial.search('foo') will now return all tutorial records that have foo in their names.
So we can create a controller that uses this new functionality:
class SearchController < ApplicationController
def show
#tutorials = Tutorial.search(params[:q])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #tutorial }
end
end
end
The corresponding view must display the tutorials. Yours doesn't. The simplest way to do this is write a partial that renders exactly one tutorial. Say it's called _tutorial.html.erb.
Then in the view for Search, you need to add
<%= render :partial => #tutorials %>
to actually display the search results.
Addition
I'll build a little example.
# Make a new rails app called learning_system
rails new learning_system
# Make a new scaffold for a Tutorial model.
rails g scaffold Tutorial name:string description:text
# Now edit app/models/tutorial.rb to add the def above.
# Build tables for the model.
rake db:migrate
rails s # start the web server
# Now hit http://0.0.0.0:3000/tutorials with a browser to create some records.
<cntrl-C> to kill the web server
mkdir app/views/shared
gedit app/views/shared/_search_box.html.erb
# Edit this file to contain just the <%= form_tag you have above.
# Now add a header at the top of any view you like, e.g.
# at the top of app/views/tutorials/index.html.erb as below
# (or you could use the layout to put it on all pages):
<h1>Listing tutorials</h1>
<%= render :partial => 'shared/search_box' %>
# Make a controller and view template for searches
rails g controller search show
# Edit config/routes.rb to the route you want: get "search" => 'search#show'
# Verify routes:
rake routes
search GET /search/:id(.:format) search#show
tutorials GET /tutorials(.:format) tutorials#index
POST /tutorials(.:format) tutorials#create
new_tutorial GET /tutorials/new(.:format) tutorials#new
edit_tutorial GET /tutorials/:id/edit(.:format) tutorials#edit
tutorial GET /tutorials/:id(.:format) tutorials#show
PUT /tutorials/:id(.:format) tutorials#update
DELETE /tutorials/:id(.:format) tutorials#destroy
# Edit app/controllers/search_controller.rb as above.
# Create app/views/tutorial/_tutorial.html.erb with following content:
<tr>
<td><%= tutorial.name %></td>
<td><%= tutorial.description %></td>
</tr>
# Edit app/views/search/show.html.erb to have following content:
<h1>Show Search Results</h1>
<table>
<%= render :partial => #tutorials %>
</table>
Now try a little test. Fill in a search criterion and press the Search button.
On Rails 6 you can use for search action implementation in the controller.rb:
def search
keyword = params[:q] #you can get this params from the value of the search form input
#posts = Post.where("title LIKE ?", "%#{keyword}%")
end
I'm having some trouble understanding the redirect_to statement.
I have a model "Book" (with an boolean attribute "read")and a controller "books". Now I created a second controller "Admins" having to methods: index and change.
The index view just renders a list off all Books with a link to the change method:
<% #Books.each do |d| %>
<%= d.title %><br>
<% if d.read==true %>
<%= link_to "mark unread", change_path(:id=>d.id)%>
<% else %>
<%= link_to "mark read", change_path(:id=>d.id)%>
<%end %>
Now the change method just changes the "read" attribute:
#book=Book.find(params[:id])
if #book.read==true
#book.update_attributes(:read => false)
else
#book.update_attributes(:read => true)
end
redirect_to action: "index"
The Problem is: rails tries to redirect me to the show action using the :id as a parameter...(perhaps because the change_url is /admins/change?id=3)
But I just want to be directed back to the index view "/admins"
is there a way? it seems like rails always tries to redirect to the view action if there is an id as a parameter
Thanks alot
PS: the routes.rb contains resources:admins and resources:books
Use this
redirect_to :controller => 'admins', :action => 'index'
Or
redirect_to admins_url
The above two will direct you to the index page of AdminsController. There is no way that Rails would route it to show action UNLESS you are redirecting to show action from the index action of AdminsController. Since, you did not share index action code of AdminsController, I would recommend you to check there.
If you want a clear explanation of redirect_to ... checkout
https://gist.github.com/jcasimir/1210155
I had a kind of similar issue some days ago. I would suggest to do this within the form where you list the books and the mark/unmark checkboxes.
<%= form_for #book,:url => book_index_path do |f| %>
This worked fine for me, when I set up a site where you create data and the user is immediately redirected to the same page (incl. success/error message).. to do a kind of
human batch-processing.
I have two models, users and materials. Users can favourite materials. I have set up the relationships and the code for favouriting works fine but I can't seem to get the code for unfavouriting right. I have the following code for unfavouriting:
Materials Controller (in show action where unfavourite form is)
#favourite = Favmat.where(:user_id => current_user.id, :material_id => #material.id)
Note: I use this code to decide which button to show in the view. Assuming a record exists we get this:
View
<%= form_for #favourite, :method => :delete do |f| %>
<%= f.submit "Unfavourite" %>
<% end %>
The problem seems to be here. Nothing I do seems to get me a working route to the destroy action in the favmats controller. I have tried using a form_tag instead but then I get very odd routes that don't work.
Favmats Controller
def destroy
Favmat.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to #material }
format.js
end
end
Update
I have also tried using link_to instead of a form. The code is as follows:
<%= link_to "Unfavourite", favmat_path, method: "delete" %>
The weird thing is that the html for this takes the favmat id from the material, not the favmat object. I don't know how to get the favmat object id in there. Nothing seems to work.
Try passing #favourite object instead of favmat_path to link_to:
<%= link_to "Unfavourite", #favourite, method: :delete %>
Okay, so I'm rebuilding an old photo gallery management app that I built a few years back in ROR 1 and running in to a few coding difficulties, since I'm rusty and apparently things have changed. My first question is I'm getting an undefined local variable or method 'gallery' error when trying to call a page. What I'm confused about is that I have the method defined in the 'gallery' controller but I'm wondering if I'm completely missing something. Here are some relevant code snippets, first is my index.html.erb page:
<% #photos.each do |photo| %>
<div>
<%= image_tag(photo.thumb_url) %>
<%= link_to 'Show', gallery %><br/>
</div>
<% end %>
<p><%= will_paginate #photos %></p>
my gallery controller:
class GalleryController < ApplicationController
skip_before_filter :authorize
# GET /gallery
# GET /gallery.xml
def index
#photos = Photo.all
#photos = Photo.paginate :page=>params[:page], :order=>'date desc',
:per_page => 2
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #gallery }
end
end
# GET /gallery/1
# GET /gallery/1.xml
def show
#photo = Photo.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #photo }
end
end
end
And my error:
undefined local variable or method `gallery' for #<#<Class:0x111127b38>:0x1112d5700>
I should clarify that "Photos" is the admin section which requires login and contains all of the fields/database/record data. I have no problem using the following line:
<%= link_to 'Show', photo %><br/>
Which brings up the correct record and viewing page, but in the admin section of the site (which requires login). Hopefully that makes sense.
Nowhere do I see you defining the variable gallery, and this is what your error message is telling you: gallery is undefined in your view.
Update RE your comments:
Just because you want the photo to go to the gallery controller doesn't mean you can just type "gallery" and expect results. This is a programming langauge, where words have meanings, and all you're doing is referencing an undefined variable. This, and nothing like this, has ever worked in any version of Rails.
If you want to route your photo to the Gallery controller, you can use the automagically generated _path helpers; specifically, gallery_path, which accepts an argument for the id of the "gallery" (really a photo) to show:
<%= link_to 'Show', gallery_path(photo.id) %><br/>
Try replacing your link_to method with something like: <%= link_to 'Show', :controller => "photos", :action => :your_method, :params1 => gallery %>.
Then in your PhotoController you can use: #my_gallery = params[:params1] to access your gallery item.
Some documentation on routes:
http://guides.rubyonrails.org/routing.html
I'm trying to learn Ruby but I geep getting this error:
The error occurred while evaluating nil.each
I was reading here the "Getting started" guide http://guides.rubyonrails.org/getting_started.html
Here's a piece of code from index.html.erb:
<h1>Listing snippets</h1>
<div class="snippets">
<% #posts.each do |post| %>
<h2><%= post.title %></h2>
<p><%= link_to 'View', post %> | <%= link_to 'Edit', edit_post_path(post) %> | <%= link_to 'Delete', post, :confirm => 'Are you sure?', :method => :delete %></p>
<% end %>
</div>
Now the #posts var in posts_controller.rb
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
end
end
What am I doing wrong?
Thanks.
PS: I see that they are displayed here http://127.0.0.1:3000/posts but what if I want to display them in the root folder (http://127.0.0.1:3000/)
You should make a partial and put that post logic inside of it.
Then you can put it on any view as long as you initialize the collection inside of each used controller action.
So in your home controller you'd still need:
#posts = Post.find(:all)
As far as your first question, try finding them via #posts = Post.find(:all)
Add a route to routes.rb (for Rails 2.x only):
map.root :controller => "posts", :action => "index"
For Rails 3.x have a look here:
http://guides.rubyonrails.org/routing.html#using-root
The error occurred while evaluating nil.each means that #posts is not an Array. Have you created a posts table?
The error is (as you probably suspected) happening in the following line:
<% #posts.each do |post| %>
Somehow #posts ends up being nil, even though we want it to be a list.
That's a little weird, because the code above looks like it should work. I'll try to help you track down the problem.
Post.all is equivalent to Post.find(:all), and according to the documentation for find, it could return nil, but I don't know when this would ever happen in practice. Normally it should return an empty list ([]) if there are no posts in the database, or raise an exception if the database table doesn't exist at all.
So just in case Post.all somehow returns nil, try #posts = [] instead of #posts = Post.all in the controller. The .each should work then.
If (as I suspect), it doesn't, my guess is that somehow a different controller from the one you posted above gets executed. Then, because #posts has never been set, trying to access it will simply give you nil, which explains the error. So check your paths and class names, and make sure that the code you think gets run actually gets run.
Hope that helps you figure out what's going wrong -- and let us know what solved the problem for you!