Rails: Couldn`t find #controller with ID of - ruby-on-rails

When submitting an answer I get this error:
ActiveRecord::RecordNotFound (Couldn't find Question with ID=answer):
app/controllers/questions_controller.rb:6:in `show'
From what I understand I either made a error with passing an argument from the form or
didn`t define it correctly in my controller.
Would appreciate some help finding this bug, thanks in advance!
Questions_Controller:
class QuestionsController < ApplicationController
def index
end
def show
#question = Question.find(params[:id])
#choices = #question.choices
end
def answer
#choice = Choice.find(:first, :conditions => { :id => params[:id] })
#answer = Answer.create(:question_id => #choice.question_id, :choice_id => #choice.id)
if Question.last == #choice.question
render :action => "thank_you"
else
question = Question.find(:first, :conditions => { :position => (#choice.question.position + 1) })
redirect_to question_path(:id => question.id)
end
end
end
views/questions/show.html.erb :
<div data-role="content">
<div align="center">
<h3><%= #question.question %></h3>
</div>
<br><br>
<ul data-role="listview">
<% #choices.each_with_index do |c, i| %>
<% i = i + 1 %>
<li data-theme="c">
<%= link_to "#{i}. #{c.choice}", answer_questions_path(:id => c.id) %>
</li>
<% end %>
</ul>
</div>
::EDIT::
This happens when I try to select a choice & submit an answer while on the first question.
Started GET "/questions/1" for 127.0.0.1 at Thu Dec 01 01:38:36 -0500 2011
Processing by QuestionsController#show as
Parameters: {"id"=>"1"}
SQL (0.6ms) SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = 1 LIMIT 1
Choice Load (10.8ms) SELECT "choices".* FROM "choices" WHERE ("choices".question_id = 1)
Rendered questions/show.html.erb within layouts/application (28.8ms)
Completed 200 OK in 424ms (Views: 118.0ms | ActiveRecord: 11.6ms)
Started GET "/questions/answer?id=1" for 127.0.0.1 at Thu Dec 01 01:38:38 -0500 2011
Processing by QuestionsController#show as
Parameters: {"id"=>"answer"}
Question Load (0.1ms) SELECT "questions".* FROM "questions" WHERE "questions"."id" = 0 LIMIT 1
Completed in 10ms
ActiveRecord::RecordNotFound (Couldn't find Question with ID=answer):
app/controllers/questions_controller.rb:6:in `show'
Hope this helps.

My best guess is that you don't have a route correctly setup. Assuming that you're using Rails 3 and you're using resources, you need to do add the following:
resources :questions do
member do
put 'answer'
end
end
This will create a route like /questions/#{id}/answer.
Answer is not an HTTP verb, so using resources in your routes will not create a route to your answer action.
Edit based on comment:
First, if you're updating or creating data, you should use put or post. It's a bad idea to modify data on the server with a get. Secondly, I assume that you would be doing an answer per question. If that is the case, you should do the action on a member, not a collection. Also, in your answer action, you have params[:id]. You won't get params[:id] if you try to do an action on a collection rather than a member.

Related

pg_search model and controller relation

This probably is a nooby one. I'm building a search form.
In the model document.rb, I have this :
pg_search_scope :search_full_text,
:against => :full_text,
:using => {
:tsearch => {
:prefix => true
}
}
and in documents_controller.rb, I have :
def find
$results = Document.search_full_text(params[:ch_acte][:text])
end
But NOTHING gets send to the database. The server log only says:
Started POST "/documents/find" for ::1 at 2017-01-19 08:48:07 +0100
Processing by DocumentsController#find as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZkqVYMuqMqnUjLer/FVdBdtv4cycp71dXqPQw6j0mfHKX5ptin7p7YiYFj8bNtjciQDmHzbKtBnZoILpGGvl8Q==", "ch_acte"=>{"text"=>"complet", "words"=>"", #[cut for brievity]}, "commit"=>"Cherche"}
Rendering documents/find.html.erb within layouts/messources
Rendered documents/find.html.erb within layouts/messources (0.4ms)
Completed 200 OK in 216ms (Views: 210.2ms | ActiveRecord: 0.0ms)
Other than the method pg_search_scope in the model and calling that method in the controller, what must I do to get this sent to the database?
When I run Document.search_full_text("esp") in rails console, it works fine.
UPDATE
I added this in documents/find.html.erb :
<% $results.each do |m| %>
<p>The id is <%= m.id %>.</p>
<% end %>
I get an page that displays my menu, and only white after that...
You should understand that Rails tries to be as performant as possible. When you build a search it does NOT execute until you attempt to access the results of the search.
So you would do...
def find
#documents = Document.search_full_text(params[:ch_acte][:text])
end
Then in your find.html.erb you might do...
<% #documents.each do |document| %>
<%= document.name %>
<% end %>
The query is only executed when the #documents.each line is executed to retrieve the documents... i.e. only when it needs to be executed.

Ruby on rails Common error: Params missing?

I am building a Order management system. I recently posted a problem about adding a order to a customer. It seems that i have fixed it for 99%. if i look in my terminal it first finds the current customer ID and then creates a new order. The following result is.
Customer Load (0.2ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = ? LIMIT 1 [["id", 111]]
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "orders" ("customer_id", "created_at", "updated_at") VALUES (?, ?, ?) [["customer_id", 111], ["created_at", "2015-11-12 13:28:21.185604"], ["updated_at", "2015-11-12 13:28:21.185604"]]
(8.2ms) commit transaction
But the problem is, it doesn't add the params. I did this intentionally just to check if my syntax would execute the following sql statement. But once i add params i get a common error "param is missing or the value is empty: order"
Here is my code:
Controller
def createorders
#customer = Customer.find(params[:id]) #find current id??
#current_user = Order.find(params[:id])
#orders = #customer.orders.new(order_params)
if #orders.save
flash[:notice] = "Subject created successfully"
redirect_to(:action => 'index')
else
#If save fails, redisplay the form so user can fix problems
render('new') #het zit in de new.html template
end
end
private
def order_params
#same as using "params[:subject]", expect that it:
# - raises an error if :subject is not present
# - allows listed attributes to be mass-assigned
params.require(:order).permit(:pakket, :verstuurt)
end
end
View
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="subject new">
<h2>Create Subject</h2>
<%= form_for(:order, :url=> {:action => 'createorders'}) do |f| %>
<table summary="subject form fields">
<tr>
<th>pakket</th>
<td><%= f.text_field(:pakket) %></td>
</tr>
<tr>
<th>verstuurt</th>
<td><%= f.text_field(:verstuurt) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Error message
ActionController::ParameterMissing in OrderController#createorders
param is missing or the value is empty: order
Extracted source (around line #107):
105
106
107
108
109
110
def order_params
params.require(:order).permit(:pakket, :verstuurt)
end
end
Serverside Log
Started GET "/order/createorders?id=111" for ::1 at 2015-11-13
11:58:30 +0100 Processing by OrderController#createorders as HTML
Parameters: {"id"=>"111"} Customer Load (0.2ms) SELECT
"customers".* FROM "customers" WHERE "customers"."id" = ? LIMIT 1
[["id", 111]] Completed 400 Bad Request in 5ms (ActiveRecord: 0.2ms)
ActionController::ParameterMissing (param is missing or the value is empty: order): app/controllers/order_controller.rb:107:in
order_params' app/controllers/order_controller.rb:44:in
createorders'
Rendered /Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb
(8.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.6ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
(1.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout (68.2ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb
(0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb
within layouts/javascript (60.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb
within layouts/javascript (0.3ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.5ms) Rendered
/Users/cecil/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb
(124.2ms)
Thank you stackoverflow for showing me support. I am new with ruby, and i understand i am making noob mistakes. So pointing out flaws are welcome!
I was ignoring your minor, non-fatal issues earlier while I was focused on locating the major issue, but I'll include them now that the major issue is apparent.
First, I'll discuss Rails naming conventions a little bit. You have two models, which are named Customer and Order. You've used the singular form of the noun for these, which is good. Each instance of a model is one thing, so it should be singular. Your controller for the Order model actions, however, should be named with the plural form, so it should be called OrdersController. This is because it controls the actions related to all of your orders. This leads us to your createorders action, which would make a little more sense if it were named createorder, since it only creates one Order. Actually, though, the convention is to name that action create. The action is in your OrdersController, so we already assume that it deals with an Order instance. (When you have Rails automatically generate REST-ful routes for a model's controller with the resources function, it assumes you have an action named create.) Lastly, in your create method, the new Order instance that will be referenced in your view should be called #order instead of #orders, since it contains only one Order.
Now things get a little more complicated. Your param is missing error means exactly that. The parameters for the new Order instance are missing. The request to the server that is producing that error is a GET request that has only one parameter, which you're providing in your URL with ?id=111. Your form's data is not being submitted to the server with that GET request. You should be doing a POST request to create a new Order. I'm going to avoid further exploration (and speculation without seeing your full code) regarding why things aren't working right now and I'll just suggest some key adjustments. It's turning in to a bit a puzzle to figure out how your app works without seeing all of the pieces.
In routes.rb, you should have this line:
resources :customers, :orders
I've made minimal changes to the view you provided, which I assume is called show.html.erb and is in your app/views/customers folder:
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="subject new">
<h2>Create Subject</h2>
<%= form_for #order do |f| %>
<table summary="subject form fields">
<tr>
<th>pakket</th>
<td><%= f.text_field(:pakket) %></td>
</tr>
<tr>
<th>verstuurt</th>
<td><%= f.text_field(:verstuurt) %></td>
</tr>
</table>
<%= f.hidden_field :customer_id %>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Here is the necessary code from customers_controller.rb to support it:
def show
customer = Customer.find params[:id]
#order = customer.orders.new
end
Notice, in the view, the parameter for form_for is the instance that was created in the controller. Also, I've added a hidden field to submit the customer_id with the new Order data.
Finally, your create action in orders_controller.rb might look like this:
def create
#order = Order.new(order_params)
if #order.save
flash[:notice] = "Subject created successfully"
redirect_to(:action => 'index')
else
render 'customers/show'
end
end
And your order_params method should be changed to include the customer_id parameter:
def order_params
params.require(:order).permit(:pakket, :verstuurt, :customer_id)
end
Notice that on a failed save, the action renders customers/show, because this is the page that they were on where the save failed. This will allow Rails to re-populate the form (in the same context) with the data that was present during the failed submission.

Ruby on Rails: read user submited .txt file into variable

I'm building a ruby on rails app that lets the user pick a file from their hard drive, and then writes specific lines from the text file into a database. I've built the form, but now I don't know how to get the content of the file into a variable, format it and then write it into the database.
I have a database table named drafts with colums set_1, set_2, set_3. I want to write line 13(from the text file) into set_1, line 165 into set_2 and line 317 into set_3. I also want to format the lines before writing them. In the file they look like this ------ FRF ------ and I only want FRF.
I've spent a lot of time searching stackoverflow and rubyonrails guides but have a hard time figuring this out. I'm very new to ruby and rails in general, so any help is appreciated.
Here's my controller (drafts_controller.rb):
class DraftsController < ApplicationController
def new
#page_title = "Upload MTGO Draft"
#draft = Draft.new
end
def create
#draft = Draft.new(draft_params)
if #draft.save
flash[:notice] = "Draft Saved!"
redirect_to drafts_show_path
else
render "new"
end
end
def index
#page_title = "MTGO Draft"
end
def show
#page_title = "MTGO Draft Replayer"
end
def search
#page_title = "Search MTGO Draft"
end
def destroy
end
def draft_params
params.require(:draft).permit(:name, :set_1, :set_2, :set3, :file_setter)
end
end
and my view: (new.html.erb):
<%= form_for #draft, :multipart => true do |f| %>
<div class="form-group">
Draft Log: <%= f.file_field :file_setter %>
<%= f.submit 'Save' %>
</div>
<% end %>
here's the model (draft.rb)
class Draft < ActiveRecord::Base
def file_setter=(file)
path = file.tempfile.to_path.to_s
lines = File.read(path).split("\r\n")
self.set_1 = lines[12]
self.set_2 = lines[164]
self.set_3 = lines[316]
end
attr_accessor :file_setter
end
If you need more info or want to get into the whole app more he's a gitHub repository.
Thanks for the help.
Here's the log excerp:
Started POST "/drafts" for 127.0.0.1 at 2015-04-10 10:52:57 +0200
Processing by DraftsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"8IjtOXuXm3fswWTslDTq5ijjo0dpCWHlu9X7UFb5prvawrZfkLC46v7PbqTgrSrvukLxAAoBIBftsGqiXv79JA==", "draft"=>{"file_setter"=>#<ActionDispatch::Http::UploadedFile:0x00000005ee4a08 #tempfile=#<Tempfile:/tmp/RackMultipart20150410-3067-1fssm13>, #original_filename="1", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"draft[file_setter]\"; filename=\"1\"\r\nContent-Type: application/octet-stream\r\n">}, "commit"=>"Save"}
[1m[36m (0.2ms)[0m [1mBEGIN[0m
[1m[35mSQL (1.8ms)[0m INSERT INTO `drafts` (`created_at`, `updated_at`) VALUES ('2015-04-10 08:52:57', '2015-04-10 08:52:57')
[1m[36m (41.6ms)[0m [1mCOMMIT[0m
Redirected to http://localhost:3000/drafts/show
Completed 302 Found in 57ms (ActiveRecord: 43.6ms)
Add this method to your model:
def file_setter=(file)
path = file.tempfile.to_path.to_s
lines = File.read(path).split("\r\n")
self.set_1 = lines[12]
self.set_2 = lines[164]
self.set_3 = lines[316]
end
In your form change the file_field value from :file to :file_setter like this:
<%= form_for #draft, :multipart => true do |f| %>
<div class="form-group">
Draft Log: <%= f.file_field :file_setter %>
</div>
<% end %>
// Its very important that you add :multipart => true to the form_for method. Otherwise file uploads wont work.
// Also add this to your model:
attr_accessor :file_setter
// In your controller you have to change this:
def draft_params
params.require(:draft).permit(:name, :set_1, :set_2, :set3)
end
To this:
def draft_params
params.require(:draft).permit(:name, :set_1, :set_2, :set3, :file_setter)
end

Attaching params to form

In my app, a micropost is simply called an "item". On each user's "show" page, there should be a form for making a new "item" that belongs to that user.
I am getting stuck making such a form.
When the form is submitted, the controller action below fires:
#user = User.find_by(name: params[:name])
#user.items.create(item_params)
redirect_to 'root'
By the way, the 'item_params' method is
params.require(:item).permit(:title, :content, :user_id)
I am getting an error about the second line. The error is
undefined method 'items' for nil:NilClass
I checked in the rails console whether I could make a new item by first selecting a user by name
#user = User.find_by(name: "tester1")
then create an item for it with the below statement:
#user.items.create(title: "new_item_title", content: "new_item_content")
and the new item was created as expected. I cannot explain the browser error, though.
EDIT
The form in question is on a "show_user". Here is the log for the HTTP request for that page:
Started GET "/center/show_user?utf8=%E2%9C%93&name=tester&commit=Search" for 12
.0.0.1 at 2014-03-19 11:46:51 -0700
Processing by CenterController#show_user as HTML
Parameters: {"utf8"=>"√", "name"=>"tester", "commit"=>"Search"}
←[1m←[35mUser Load (1.0ms)←[0m SELECT "users".* FROM "users" WHERE "users"."
ame" = 'tester' LIMIT 1
Rendered center/show_user.html.erb within layouts/application (2.0ms)
Completed 200 OK in 23ms (Views: 18.7ms | ActiveRecord: 1.0ms)
The form is hosted on this page. Here is the request that is sent with submission of the form:
Started POST "/center/show_user" for 127.0.0.1 at 2014-03-19 11:47:14 -0700
Processing by CenterController#create_item_owned as HTML
Parameters: {"utf8"=>"√", "authenticity_token"=>"P6mb63rhTHx6Q17zhfu4WXErG5Pb0
8t0d/L1RppKAl0=", "item"=>{"title"=>"uno", "content"=>"uno1"}, "commit"=>"Save I
tem"}
←[1m←[36mUser Load (1.0ms)←[0m ←[1mSELECT "users".* FROM "users" WHERE "users
"."name" IS NULL LIMIT 1←[0m
Completed 500 Internal Server Error in 4ms
NoMethodError (undefined method `items' for nil:NilClass):
app/controllers/center_controller.rb:18:in `create_item_owned'
So no information about the user is being passed along with the parameters when the form is submitted. How how I fix this?
Here are my relevant routes:
get "center/show_user/" => 'center#show_user'
post "center/show_user" => 'center#create_item_owned'
The "create_item_owned" action is the one described at the beginning of this question.
The "show_user" action is
#user = User.find_by(name: params[:name])
#new_item = Item.new
How should I forward along those parameters in such a way that the new object created by the form is automatically associated with the specific user in the database (along with automatic creation of foreign keys)?
My form is
<%= form_for :item do |x| %>
Title: <%= x.text_field :title %> <br>
Content: <%= x.text_field :content %> <br>
<%= x.submit %>
<% end %>
I think you might still have to find by id rather than by name. The name might not be passed in the params. You should check your logs to see what params are being sent.

Rails Routing to grandparent nested class

I'm having a problem with a nested routing when I try to edit the subresource (lessons) from it's show page by clicking the edit link as described below. There are two classes involved: Units and Lessons. I can't understand why Rails is trying to route to course controller (a parent of Units).
Any help would be greatly appreciated.
I am getting this error and url
http://localhost:3000/units/3/lessons/13/edit
Routing Error
No route matches {:action=>"show", :controller=>"courses", :id=>nil}
config/routes.rb
resources :courses do
resources :units
end
resources :units do
resources :lessons
end
** from rake routes**
unit_lessons GET /units/:unit_id/lessons(.:format) lessons#index
POST /units/:unit_id/lessons(.:format) lessons#create
new_unit_lesson GET /units/:unit_id/lessons/new(.:format) lessons#new
edit_unit_lesson GET /units/:unit_id/lessons/:id/edit(.:format) lessons#edit
unit_lesson GET /units/:unit_id/lessons/:id(.:format) lessons#show
code for clicked link
<%= link_to "Edit Lesson", edit_unit_lesson_path(#unit, #lesson ) %>
LessonsController
class LessonsController < ApplicationController
before_filter :find_unit
before_filter :find_lesson, :only => [:show,:edit,:update,:destroy]
.
.
.
private
def find_unit
#unit = Unit.find(params[:unit_id])
end
def find_lesson
#lesson = #unit.lessons.find(params[:id])
end
Server Log File
Started GET "/units/3/lessons/12/edit" for 127.0.0.1 at 2012-08-02 14:50:55 +0200
Processing by LessonsController#edit as HTML
Parameters: {"unit_id"=>"3", "id"=>"12"}
Unit Load (0.1ms) SELECT "units".* FROM "units" WHERE "units"."id" = ? LIMIT 1 [["id", "3"]]
Lesson Load (0.1ms) SELECT "lessons".* FROM "lessons" WHERE "lessons"."unit_id" = 3 AND "lessons"."id" = ? LIMIT 1 [["id", "12"]]
Rendered lessons/_form.html.erb (3.4ms)
Rendered lessons/edit.html.erb within layouts/application (4.4ms)
Completed 500 Internal Server Error in 7ms
ActionController::RoutingError (No route matches {:action=>"show", :controller=>"courses", :id=>nil}):
app/views/lessons/edit.html.erb:8:in `_app_views_lessons_edit_html_erb___3830769233446763788_70188197130200'
Found it. The link was part of a table body, built with an .each iterator. I needed to change the name from "#lesson" to "lesson" as that is what is referenced when the table is built.
For anyone else stuck on a similar problem, I've put the functioning code below.
<tbody>
<% #unit.lessons.each do |lesson| %>
<tr>
<td><%= link_to lesson.lesson_name, [#unit, lesson] %></td>
.
.
.
<td><%= link_to 'Edit', edit_unit_lesson_path(#unit, lesson ) %></td>
</tr>
<% end %>
</tbody>

Resources