Ruby on Rails, get objects out of contoller - ruby-on-rails

My update.html.erb:
<% #uploads.each do |upload| %>
<p><%= upload.name %></p>
<p class="grey">
<%= best_in_place upload, :place, type: :select, collection: [ ["Home", "Home"],["Sauna", "Sauna"]]%>
</p>
<%end%>
controller:
def show
#uploads = Upload.all
end
def update
#uploads = Upload.all
#upload = Upload.find(params[:id])
respond_to do |format|
if #upload.update_attributes(params[:upload])
format.html { redirect_to #upload, notice: 'Upload was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #upload.errors, status: :unprocessable_entity }
end
end
end
The problem is that I get the error: undefined methodeach' for nil:NilClass` , meaning that my controllers do not pass my object to the variable #uploads. Why do not the do that and how can I fix it? Thanks in advance.
ps. I could write at the top of my view something like this:
<% #uploads=Uploads.all%>
But that is not the best idea.
Thanks in advance

<% #uploads.each do |upload| %>
<%end if #uploads.present? %>

IF your routes are RESTful routes, the update method is a HTTP PUT method and it shouldn't have a template. What you are looking for is a edit action:
def edit
#uploads = Upload.all
end

#katja: Referring to your comment.
update is a HTTP PUT request, you cant get a record in that but edit is a get request you can get all records in edit action.
You can add a before_filter callback to your edit action.
before_filter :get_all_uploads, only: [:edit]
def get_all_uploads
#uploads = Upload.all
end
And in your edit.html.erb you can do
<% #uploads.each do |upload| %>
<p><%= upload.name %></p>
<p class="grey">
<%= best_in_place upload, :place, type: :select, collection: [ ["Home", "Home"],["Sauna", "Sauna"]]%>
</p>
<% end %>

Related

param is missing or the value is empty: room

i created an edit page to edit the room(model) and update the form to change the current name and current capacity to whatever we wish but i am getting an error
ActionController::ParameterMissing in RoomsController#edit
param is missing or the value is empty: room
rooms_controller.rb
class RoomsController < ApplicationController
before_action :set_room, only: %i[show edit update]
def index
#rooms = Room.all
end
def show
end
def new
#room = Room.new
end
def create
#room = Room.new(room_params)
respond_to do |format|
if #room.save
format.html { redirect_to room_url(#room), notice: "Room was created Successfully" }
else
format.html { render :new, status: :unprocessable_entity }
end
end
end
def edit
respond_to do |format|
if #room.update(room_params)
format.html { redirect_to room_url(#room), notice: "Room was successfully updated!" }
else
format.html { render :edit, status: :unprocessable_entity }
end
end
end
private
def set_room
#room = Room.find(params[:id])
end
def room_params
params.require(:room).permit(:name, :capacity)
end
end
edit.hml.erb
<h2>Edit Room</h2>
<%= render "form", room: #room %>
_form.html.erb
<%= form_with(model: room) do |form| %>
<% if room.errors.any? %>
<div style="color: red">
<h2><%= pluralize(room.errors.count, "errors") %> Prohibited this Room from saving</h2>
<ul>
<% room.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :name, style: "display: block" %>
<%= form.text_field :name %>
</div>
<div>
<%= form.label :capacity, style: "display: block" %>
<%= form.number_field :capacity %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
i am using the same partial _form.html.erb for both new.html.erb and edit.html.erb , is it because of using same partial form for edit and new or there is some other reason?
new.html.erb
<h1>New Room</h1>
<%= render "form", room: #room %>
You're using the wrong action.
In Rails flavored REST the edit action responds to a GET /rooms/:id/edit request and just renders the form. It should also be idempotent. There is no room parameter since you're not responding to a form submission.
Updating the resource is done in the update method (PATCH /rooms/:id).
class RoomsController < ApplicationController
# ...
# you can actually completely omit this method
# Rails will implicitly render edit.html.erb anyways
# GET /rooms/1/edit
def edit
end
# PATCH /rooms/1
def update
# you don't need to use MimeResponds if you're only responding to HTML requests. KISS
if #room.update(room_params)
redirect_to #room, notice: "Room was successfully updated!"
else
render :edit, status: :unprocessable_entity
end
end
# ...
end

Couldn't find Comment with 'id'=3 with nested resources

im getting this error:
https://imgur.com/a/Mrvkm2Z
I can create comments in mi course post but i can't edit them because of this error
I don't know how to solve this, I was looking everywhere but nothing that helps me solve the problem
EDIT
here is my code in comments controller
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /comments
# GET /comments.json
def index
#comments = Comment.all
end
# GET /comments/1
# GET /comments/1.json
def show
end
# GET /comments/new
def new
#course = Course.find(params[:course_id])
#comment = #course.comments.build
end
# GET /comments/1/edit
def edit
end
# POST /comments
# POST /comments.json
def create
#course = Course.find(params[:course_id])
#comment = #course.comments.build(comment_params)
respond_to do |format|
if #comment.save
format.html { redirect_to #course, notice: 'Comment was successfully created.' }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
respond_to do |format|
if #comment.update(comment_params)
format.html { redirect_to #comment, notice: 'Comment was successfully updated.' }
format.json { render :show, status: :ok, location: #comment }
else
format.html { render :edit }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to comments_url, notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:title, :body)
end
end
so i think the problem might be in create and new, i dont know how to connect the models with one-to-many, i was able to create comments in my course but when i wanted to edit 1 of the comments apiers that error and in every comment i click to edit sends me to the same url with the same error id=3 not found
Also this are my html code(maybe the errors can be there too):
<%= form_for #comment, :url => course_comments_path(params[:course_id]) do |f| %>
<% if comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title, id: :comment_title %>
</div>
<div class="field">
<%= f.label :body %>
<%= f.text_area :body, id: :comment_body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
and the show.html for my courses:
<% if current_user%>
<p id="notice"><%= notice %></p>
<p>
<h1><%= #course.name %></h1>
</p>
<p>
<h2>Comentarios del curso:</h2>
</p>
<p>
<% #course.comments.each do |comment| %>
<h3><%= comment.title %></h3>
<p><%= comment.body %></p>
<%if current_user.admin%>
<%= link_to 'Edit', edit_course_comment_path(#course) %>
<%end%>
<%end%>
</p>
<%if current_user.admin %>
<%= link_to 'Postear', new_course_comment_path(#course)%>
<%= link_to 'Edit', edit_course_comment_path%>
<%= link_to 'Back', authenticated_root_path %>
<%else%>
<%= link_to 'Postear', new_course_comment_path(#course) %>
<%= link_to 'Back', authenticated_root_path %>
<%end%>
First off you have a strange mix of shallow nesting and deep nesting. Shallow nesting is a routing option that effects the nesting of member routes.
resources :courses do
# GET|PUT|PATCH|DELETE /courses/:course_id/comments/:id
# GET /courses/:course_id/comments/:id/edit
resources :comments
# GET|PUT|PATCH|DELETE /comments/:id
# GET /comments/:id/edit
resources :comments, shallow: true
end
I would generally recommend shallow nesting - unless the child only can exist in the scope of its parent or is only unique in the scope of its parent. And your controller is setup for shallow nesting. Just make sure you edit those comments from the scaffold so that they actually document the right paths.
Besides the routes you also need to use the correct link helpers:
# deep nesting
link_to 'Edit', edit_course_comment_path(#course, #comment)
# shallow nesting
link_to 'Edit', edit_comment_path(#comment)
If you really need to support both you can use the polymorpic route helpers:
link_to 'Edit', [:edit, #course, #comment]
To create forms for nested resources pass an array containing the parent and child:
form_for([#course, #comment])
# or in rails 5+
form_with(model: [#course, #comment])
This works perfectly fine with both deep and shallow nesting as well as Rails compacts the array. This also lets you use the same form partial for creating and updating.
Explicitly passing the URL for a form in Rails is redundant 99% of the time. If you just follow the conventions Rails is smart enough to figure out the correct path for creating and updating.
I think this line
<%= link_to 'Edit', edit_course_comment_path(#course) %>
should be
<%= link_to 'Edit', edit_course_comment_path(#course, comment) %>
You need both ids of the course and the comment.

Rails: undefined method `each' for nil:NilClass

I want to build a for loop but I an this error.
undefined method `each' for nil:NilClass
That is the part of the view, which gives me the error:
<% #deadlines.each do |deadline| %>
<% if Time.now < deadline.deadline %>
<%= form_for(current_user) do |f| %>
<%= f.hidden_field :enrolled, :value => true %>
<%= f.submit "Anmeldung bestätigen", class: "btn btn-primary" %>
<% end %>
<% end %>
<% end %>
Seems like #deadlines is not recognized, even though I already used the same loop in the Index view of the deadlines folder. How can I use the same variable in my homepage view?
Thanks a lot!
Here is the Controller, maybe it also gives you some information:
class DeadlinesController < ApplicationController
before_action :set_deadline, only: [:show, :edit, :update, :destroy]
# GET /deadlines
# GET /deadlines.json
def index
#deadlines = Deadline.all
end
# GET /deadlines/1
# GET /deadlines/1.json
def show
end
# GET /deadlines/new
def new
#deadline = Deadline.new
end
# GET /deadlines/1/edit
def edit
end
# POST /deadlines
# POST /deadlines.json
def create
#deadline = Deadline.new(deadline_params)
respond_to do |format|
if #deadline.save
format.html { redirect_to #deadline, notice: 'Deadline was successfully created.' }
format.json { render :show, status: :created, location: #deadline }
else
format.html { render :new }
format.json { render json: #deadline.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /deadlines/1
# PATCH/PUT /deadlines/1.json
def update
if #deadline.update(deadline_params)
flash[:success] = "Die Deadline wurde erfolgreich aktualisiert."
redirect_to deadlines_path
else
flash[:error] = "Die Deadline wurde nicht aktualisiert."
end
end
# DELETE /deadlines/1
# DELETE /deadlines/1.json
def destroy
#deadline.destroy
respond_to do |format|
format.html { redirect_to deadlines_url, notice: 'Deadline was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_deadline
#deadline = Deadline.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def deadline_params
params.require(:deadline).permit(:deadline)
end
end
Your #deadlines is empty now, use this #deadlines = Deadline.all to your homepage controller action and each block modify like this
<% if #deadlines.present? %>
<% #deadlines.each do |deadline| %>
<% if Time.now < deadline.deadline %>
<%= form_for(current_user) do |f| %>
<%= f.hidden_field :enrolled, :value => true %>
<%= f.submit "Anmeldung bestätigen", class: "btn btn-primary" %>
<% end %>
<% end %>
<% end %>
<% else %>
Deadline is empty
<% end %>
When #deadlines is empty then it will show Deadline is empty

Updating database Model view controller rails 4 method

I want to call a method that updates an attribute when saved.
Here is my index.html.erb
<% #users.each do |user| %>
<div>
<strong><%= user.email %></strong>
</div>
<% if can? :update, User %>
<%= link_to 'Make Author', User, method: :add_roles %>
<% end %>
Below is my user_controller.rb
def add_roles
respond_to do |format|
if #user.update(user_params)
user.author = true
user.save!
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
It doesn't update the attribute though. I think it is because I am not properly attaching it to the correct user. I want to current_user to update another user.
I think the solution is simple, first do what avlazarov said in his comment:
In the view <%= link_to 'Make Author', "/users/#{user.id}/add_roles",
method: :patch %> In the routes.rb patch '/users/:id/add_roles' =>
'user#add_roles'
Or something simpler, in routes.rb:
resources :users do
patch :add_roles, on: :member
end
then in view:
<%= link_to 'Make author', add_roles_users_path(user) %>
Then rename user_controller.rb placed in app/controllers to users_controller.rb and make sure the class name is UsersController.

undefined method `errors' for nil:NilClass

Here is my Edited details:
I have my controller like,
class Enr::Rds::SurvRdsapXrefsController < Enr::Controller
def index
#enr_rds_surv_rdsap_xrefs = Enr::Rds::SurvRdsapXref.paginate(page: params[:page])
end
def show
end
def new
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
def edit
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.find(params[:id])
end
def create
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new(params[:enr_rds_surv_rdsap_xref])
respond_to do |format|
if #enr_rds_surv_rdsap_xref.save
format.html { redirect_to :enr_rds_surv_rdsap_xrefs, notice: "Survey link was successfully created." }
format.js
format.json { render json: #enr_rds_surv_rdsap_xref, status: :created, location: #enr_rds_surv_rdsap_xref }
else
format.html { render action: "new" }
format.js
format.json { render json: #enr_rds_surv_rdsap_xref.errors, status: :unprocessable_entity }
end
end
end
def update
end
def destroy
end
end
Here is my view form like
<%= form_for(#enr_rds_surv_rdsap_xref, :remote => true) do |f| %>
<% if #enr_rds_surv_rdsap_xref.errors.any? %>
<div id="error_explanation">
<div class="validate">
The form contains <%= pluralize#enr_rds_surv_rdsap_xref.errors.count, "error") %>.
</div>
<ul>
<% #enr_rds_surv_rdsap_xref.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="control-group">
<%= f.label :section %><br />
<%= f.text_field :section %>
</div>
<%= f.submit %>
<% end %>
When i click the index page to create a new link, the index page showing error like
NoMethodError in Enr/rds/surv_rdsap_xrefs#index
undefined method `errors' for nil:NilClass
Thanks for the suppport and please suggest me to rectify the error. I am new to ROR. Thanks
Your error reveals that the rendering of the index template is causing the error, which means you're rendering the form for the new survey (the code snippet above) in the index template. This is fine, but if you're going to do that, you'll have to instantiate a new survey in index, as well as in new.
At the simplest, you could just copy the code in new to index:
def index
#enr_rds_surv_rdsap_xrefs = Enr::Rds::SurvRdsapXref.paginate(page: params[:page])
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
def new
#enr_rds_surv_rdsap_xref = Enr::Rds::SurvRdsapXref.new
end
To keep your code a bit DRYer you might change where the new instance is created. A pattern you'll often see is something similar to:
before_filter :build_record, :only => [:new, :index]
protected
def build_record
#survey = YourSurvey.new
end
This way you don't even need to write the new/index methods if you don't have any other logic.
Do you also set #survey in the new action in your controller? The error means that when the view is rendered #survey is nil, so there must be a problem with setting that instance variable.
Do you get the error when you go to the 'new' view or when you try to submit the form (create)?
The form contains <%= pluralize#enr_rds_surv_rdsap_xref.errors.count, "error") %>
This line of the code is the problem. You are lacking a "(" between the pluralize and the #enr...
Explained: RoR thinks that the object is: pluralize#enr... instead of the # All alone, and he has no errors for this kind of object.

Resources