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
Related
I use wkhtmltopdf to convert a page to pdf
<%= link_to "download" user_group_assessments_path(#user, #group, #assessment, format: 'pdf') =>
It will go to my AssessmentsController and call my index method, it looks like:
#assessments = Assessment.all
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
end
end
end
In show.pdf.erb I access user, group and assessment.
Every thing is ok and it works without any problem. But when I call
<% #assessment.measurements.each do |m| %>
...
<% end %>
I get the following error:
Undefined method 'measurements' for nil:NilClass
And it points to the line where I am trying to access measurement.
How can I access the model 'measurement' from this file?
You need to send your assessment details to your view. for example:
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
locals: {:assessment => #assesment}
end
end
Then in your view assessment can be accessed as
<% assessment.measurements.each do |m| %>
...
<% end %>
In controller your variable is #assessments but for iteration you are trying to use #assessment which is missing plural s. Try as following
<% #assessments.each do |assessment| %>
<% assessment.measurements.each do |m| %>
...
<% end %>
<% end %>
Or, you must need an #assessment instance variable in your controller action. and then you can use following loop
<% #assessment.measurements.each do |m| %>
...
<% end %>
Try to this if you have an association with measurements
#assessments = Assessments.joins(:measurements)
and in your view do this
#assessments.each do |assessment|
assessment.measurements.each do |measurement|
perform operations
end
end
As I mentioned above, I wrote the following code in index action:
respond_to do |format|
format.html
format.pdf do
render pdf: "filename"
template: "assessments/show.pdf.erb"
end
end
But that was wrong, because I am trying to access #assessment, where the #assessment defined in show action, not in index action. In index all assessments are defined, not a specific one. And I need just one with a specific id.
Also, putting the code in show method instead of index solved the problem.
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 making resourceful routes for youtube videos. So, a person just pastes the youtube embed link in the form. In the controller I have a normal set of resourceful actions:
class VideosController < ApplicationController
def index
#videos = Video.all
end
def new
#video = Video.new
end
def create
Video.create(params[:video])
redirect_to :action => :index
end
def destroy
Video.destroy(params[:id])
redirect_to :action => :index
end
end
And in the view I'm just displaying it: (in Haml)
- #page_title = 'Video'
#videos
%ul
= list_of(#videos) do |video|
%h1= video.title
!= video.link
= link_to "Delete", video_path(video), :method => :delete
= link_to "Add new video", new_video_path
%p#top
= link_to 'Go to top ↑', '#'
For the one who don't use Haml, != escapes the string. video.link holds the YouTube embed code
The problem is that, when I create a new video, and when it redirects me back to the index page, the newly created video isn't displayed (the other ones are normally displayed). Only after I refresh the page, it's normally displayed.
I saw in the web inspector that the src attribute is missing from the iframe (so that's why the video isn't displayed). But when I look in the page source, everything is normal there. So, thinking it may be Javascript's fault, I tried disabling it. But nothing changed.
I don't think you want to escape it using haml... I think you want to call
video.link.html_safe
Note: if the user is pasting in the link, this is very unsafe.
Update --- If you have the javascript develop console open, you'll see this error pop up:
**Refused to execute a JavaScript script. Source code of script found within request.**
Check this answer for why it's refusing to due XSS Here's a method that is both safe and works. You'll paste in the youtube ID in the text field: ibWYROwadYs
index.erb
<% if session[:youtube].present? %>
<iframe width="480" height="360" src="http://www.youtube.com/embed/<%=session[:youtube]%>" frameborder="0" allowfullscreen></iframe>
<% end %>
<%= form_tag load_path do %>
<%= text_field_tag :youtube_id %>
<%= submit_tag "Submit" %>
<% end %>
<%= link_to "Clear", clear_path, :method => :delete %>
home_controller.rb
class HomeController < ApplicationController
def index
end
def smth
session[:youtube] = params[:youtube_id]
redirect_to :action => :index
end
def clear
session.clear
redirect_to :action => :index
end
end
I am new to rails and try to realise a overview of a list of meetings created using the index method in the meeting controller. The page has also a select with all years, so that you can select a specific year to see only the meetings of the selected year. I realized it adding a form on the page:
index.html.erb:
<h1>Protokolle</h1>
<%= form_tag 'meetings', :method => :get do %>
<%= select_tag :selected_year, options_for_select(available_years, #year), {onchange: 'this.form.submit();'} %>
<% end %>
<%= link_to image_tag('new'), new_meeting_path %>
...
Using put as the action method of the form, does not work, but get seems to be ugly.
How can this be done better?
meetings_controller:
class MeetingsController < ApplicationController
def index
#year = selected_year(params[:selected_year])
#meetings = Meeting.where(:held_on => ("01.01.#{#year}".to_date)..("31.12.#{#year}".to_date)).order('held_on desc').all
respond_to do |format|
format.html # index.html.erb
end
end
...
Thanks for your tips ...
There's no problem using GET in a form for a get-only action. PUT doesn't work, because of RESTful routes - the POST version would activate the 'meetings' route will call 'create' for a new meeting, PUT is simply denied by the router as not existing.
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).