link_to create new nested_resource - ruby-on-rails

I defined the next things:
task.rb:
class Task < ActiveRecord::Base
belongs_to :worker
attr_accessible :done, :name
end
worker.rb:
class Worker < ActiveRecord::Base
has_many :tasks
attr_accessible :name
end
I wrote the next code in "views/workers/index.html.erb":
<h1>Listing workers</h1>
<table>
<tr>
<th>Name</th>
<th>Task</th>
<th>Done</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #workers.group_by(&:name).each do |name, tasks| %>
<tr>
<td><%= name %></td>
<td><%= tasks.size %></td>
<td><%= tasks.select{ |task| task.done != 'yes' }.size %></td>
<td><%= link_to 'new Task', new_worker_task_path(name) %></td>
<td><%= link_to 'Show Tasks', worker_tasks_path(name) %></td>
</tr>
<% end %>
</table>
in order to use the link of: new_worker_task_path,
I defined in the task_controller:
def new
#worker = Worker.find(params[:worker_id])
#task = #worker.tasks.new
respond_with(#worker)
end
In addition, I defined: new.html.erb in the views/tasks, that also has: "Hi".
When I pressed the link of: "new task", I got:
Couldn't find Worker with id=alon
Rails.root: /home/alon/projects/TODO
Application Trace | Framework Trace | Full Trace
app/controllers/tasks_controller.rb:48:in `new'
Request
Parameters:
{"worker_id"=>"alon"}
first question: how can I find the worker who I want to add him a task?
second question: as I said, I defined:
<td><%= link_to 'new Task', new_worker_task_path(name) %></td>
why should I have to send the name? I use this value? I don't really understand why this parameter is necessary..

You have to send actual :param_key, which by default is ID.
So,
new_worker_task_path()
# have to receive worker's ID as argument. Or worker object, accepted too...
new_worker_task_path(#worker)
Updated for the 1st question:
Let me guess what you want.
<% #workers.group_by(&:name).each do |name, workers| %>
<tr>
<td><%= name %></td>
<td><%= workers.map {|w| w.tasks.size}.sum %></td>
<td><%= workers.map {|w| w.tasks.select{ |task| task.done != 'yes' }.size}.sum %></td>
<td>
<% workers.each do |worker| %>
<%= link_to 'new Task', new_worker_task_path(worker) %>
<% end %>
</td>
<td>
<% workers.each do |worker| %>
<%= link_to 'Show Tasks', worker_tasks_path(worker) %>
<% end %>
</td>
</tr>
<% end %>

Related

submit_tag with check_box_tag returning error

I'm having some trouble with check_box_tag and my method enable (a product can be disabled) in Ruby on Rails.
I created some checkbox so the user select the products that he wants to set enable = true.
Keeps returning the error "Couldn't find Product with 'id'=enable"
My method enable:
def enable
Product.update_all(["enable=?", true], :id => params[:selected_products])
redirect_to root_url
end
My routes.rb:
Rails.application.routes.draw do
get 'product_export/new'
get 'product_imports/new'
resources :users
resources :product_imports
resources :products do
collection do
post :import
post :export
post :enable
end
end
root to: 'products#index'
end
and finally my view with the table e the check_box_tag:
<%= form_tag enable_products_path, :method => :put do %>
<%= submit_tag "Enable products" %>
<table class="table table-striped table-responsive" id="productsTable">
<thead class="thead-inverse">
<tr>
<th/>
<th>Code</th>
<th>Enable</th>
<th>Bar code</th>
<th>Unit cost</th>
<th>Description</th>
<th>Family</th>
<th>Final</th>
<th>Measure</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #products.each do |product| %>
<tr>
<td><%= check_box_tag 'selected_products[]', product.id %></td>
<td><%= link_to (product.code), edit_product_path(product) %></td>
<td><%= product.enable %></td>
<td><%= product.bar_code %></td>
<td><%= product.unit_cost %></td>
<td><%= product.description %></td>
<td><%= product.family %></td>
<td><%= product.final %></td>
<td><%= product.measure %></td>
<td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
Thanks for the help!
Use where to find selected products and when to update them:
Product.where(id: params[:selected_products]).update_all(enable: true)

show products that belong to orders on admin pannel

I am trying to show the name of each product that belongs to an order on my admin panel but I cant seem to get it.
here are my associations:
OrderItem belongs_to :product
OrderItem belongs_to :order
Product has_many :order_items
Order has_many :order_items
I have tried two different things:
<tbody>
<% #orders.each do |order| %>
<tr>
<td><%= order.id %></td>
<td><%= order.order_items.product.name %></td>
<td><%= order.total %></td>
</tr>
<% end %>
</tbody>
This gets me this error:
undefined method `name' for #<Array:0x0000000535fbb0>
So then I try to loop through like this:
<tbody>
<% #orders.each do |order| %>
<tr>
<td><%= order.id %></td>
<% order.order_items each do |order_item| %>
<% order_item.products each do |product| %>
<td><%= product.name %></td>
<% end %>
<% end %>
<td><%= order.total %></td>
</tr>
<% end %>
</tbody>
And I get this error:
undefined local variable or method `each' for <Class:0x007fce540aa3f0>:0x007fce5417fed8>
Here is my controller code:
def orders
#orders = Order.all
#order_items = OrderItem.all
#products = Product.all
end
I am not sure where I am going wrong any help would be appreciated, thanks.
You can do this in either way you suggest: just keep an eye on your collections vs. items
First Way:
This one puts all your items in a single <td>
<tbody>
<% #orders.each do |order| %>
<tr>
<td><%= order.id %></td>
<td><%= order.order_items.map{ |o| o.product.name }.join(', ') %></td>
<td><%= order.total %></td>
</tr>
<% end %>
</tbody>
Second Way:
Here, each order_item gets its own <td>
<tbody>
<% #orders.each do |order| %>
<tr>
<td><%= order.id %></td>
<% order.order_items each do |order_item| %>
<td><%= order_item.product.name %></td>
<% end %>
<td><%= order.total %></td>
</tr>
<% end %>
</tbody>
You might consider adding some has_many through or delegate relationships in your models in the long term - it will make this kind of association a little tidier.

Simple range search in Rails

I'm new to ROR and I'm trying to implement a simple search which should allow a user to search for hikes that match a certain range of difficulty. The form is properly displayed and I do not get any error messages, the problem is that no search results are dispayed.
I've been trying to solve this for a whole day now, so any help is extremely appreciated!
Index.html.erb
<%= form_tag wanderungens_path, :method => 'get' do %>
<p>
<%= number_field_tag ':search[dauer_von]', #search.dauer_von %>
<%= number_field_tag ':search[dauer_bis]', #search.dauer_bis %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
Wanderungens_controller.rb
def index
#search = WanderungenSearch.new(params[:search])
#wanderungens = #search.scope
end
wanderungen_search.rb
class WanderungenSearch
attr_reader :dauer_von, :dauer_bis
def initialize(params)
params ||= {}
#dauer_von = params[:dauer_von]
#dauer_bis = params[:dauer_bis]
end
def scope
Wanderungen.where('zeitdauer BETWEEN ? AND ?', #dauer_von, #dauer_bis)
end
I followed this tutorial: https://www.youtube.com/watch?v=Ri1YNjl1_hA
I'm on Rails 4.0.0 and Ruby 2.0.0
Update: This is the code where #Wanderungens is displayed:
<table>
<thead>
<tr>
<th>Description</th>
<th>User</th>
<th>Schwierigkeitsgrad</th>
<th>Zeitdauer</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% #wanderungens.each do |wanderungen| %>
<tr>
<td><%= wanderungen.description %></td>
<td><%= wanderungen.user.email if wanderungen.user %></td>
<td><%= wanderungen.schwierigkeitsgrad.description if wanderungen.schwierigkeitsgrad %></td>
<td><%= wanderungen.zeitdauer if wanderungen.zeitdauer %></td>
<td><%= link_to 'Show', wanderungen %></td>
<td><%= link_to 'Edit', edit_wanderungen_path(wanderungen) %></td>
<td><%= link_to 'Destroy', wanderungen, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
If I search from 1 to 2, the following request is generated:
http://localhost:3000/wanderungens?utf8=%E2%9C%93&%3Asearch[dauer_von]=1&%3Asearch[dauer_bis]=2

Rails 3 task scopes?

I am working on a simple rails 3 todo application and I am trying to filter the app by completed tasks and none completed task but whenever I try calling a scope I get the error message.
undefined method `completed' for #<Array:0x007fe8420d0e58>
task.rb
scope :completed , where(:completed => true)
scope :incomplete , where(:finished => false)
index.html.erb
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Finished</th>
<th>User</th>
</tr>
<% #tasks.each do |task| %>
<tr>
<td><%= task.name %><%= button_to "complete", complete_task_path(task.id)%></td>
<td><%= task.description %></td>
<td><%= task.finished %></td>
<td><%= task.user_id %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<%= content_tag :h2, "Stuff Ive done" %>
<table>
<tr>
<th>Name</th>
</tr>
<% #tasks.completed.each do |task| %>
<tr>
<td><%= task.name %></td>
</tr>
<% end %>
</table>
task_controller.rb
def complete
#task = Task.find(params[:task_id])
#task.completed = true
#task.save
redirect_to task_path
end
routes.rb
match "tasks/:id/complete" => "task#complete", :as => :complete_task
Any reasons why rails is giving me this error?
Just by looking at your view (index.html.erb), in one place, you are treating as a relation.
<% #tasks.each do |task| %>
Later in the code, you are trying to access it as a single object.
<% #tasks.completed.each do |task| %>
Since you are seeing the error on the second instance, you need to access 'completed' as in:
<% #tasks.completed.each do |task| %>
<% completed = task.completed %>
<% completed.each do |com| %>
Does this make sense?

how to display errors notice in Rails?

Hi I have the following code in my model:
class Product < ActiveRecord::Base
before_destroy :check_tasks
has_many :tasks, :order => 'created_at DESC'
validates :name, :presence => true
belongs_to :sprint
validates :sprint_id, :presence => true
def check_tasks
if self.tasks.any?
errors.add_to_base "Product has tasks and cannot be destroyed."
return false
end
end
end
When I am in the product view which lists all the products, I would like to display the error message on the top of the view, every time someone tries to delete a product which has tasks linked to it. I want the message: Product has tasks and cannot be destroyed displayed.
What code should I put in the view below? The view is the product view, which is in the views/products folder.
Thanks!!!
<h1>Listing products</h1>
<%= link_to 'New Product', new_product_path %>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Sprint</th>
<th></th>
<th></th>
<th></th>
</tr>
<% if not #messages_rendered -%>
<% if flash[:error] -%>
<p class='error'><%=h flash[:error] %></p>
<% end -%>
<% if flash[:notice] -%>
<p class='notice'><%=h flash[:notice] %></p>
<% end -%>
<% end -%>
<% #messages_rendered = true -%>
<% #products.each do |product| %>
<tr>
<td><%= product.name %></td>
<td><%= product.description %></td>
<td><%= product.sprint.name %></td>
<td><%= link_to 'Show', product %></td>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td><%= link_to 'Destroy', product, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
Try putting this in your product_controller:
def destroy
...
flash[:error] = #product.errors.full_messages.join(' ')
...
end

Resources