I have a bug in my HTML ERB file for Rails - ruby-on-rails

I want to create a text field that accepts input and when you press the button next to it, it will save these changes to the database. It will be a PUT request, updating the value in the database for this specific user (not the logged in user, this is a page for admins to update values for users).
This is what the structure should be, (code to follow below):
1) Create text field and button for this in show.html.erb
2) Create a function called set_wistia_project_ID for this in users_controller.rb, set button equal to this :action
3) Create a helper function called set_project_id in user.rb that is called by set_wistia_project_ID, which actually updates the database. I decided to split it up into two functions because I noticed a lot of Rails projects tend to separate and break up functionality into the controller and model.
4) Edit my routes.rb to include some strange code, which I'll be honest, have no idea what it actually does. But without it, the entire app crashes on Heroku. So I leave it there. Found from a StackOverflow post.
My show.html.erb:
<% provide(:title, #user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
<br>
<%= #user.email %>
<br>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :wistia_project_id %>
<%= f.text_field :wistia_project_id, class: 'form-control' %>
<%= button_to "Save", :action => "set_wistia_project_ID", :method => :put, :form_class => "form-control" %>
</div>
</div>
</h1>
</section>
</aside>
</div>
My users_controller.rb:
# Sets wistia_project_ID.
def set_wistia_project_ID
#user = User.find(params[:id])
#user.set_project_id
end
My user.rb:
# Sets the wistia_project_ID.
def set_project_id
self.wistia_project_ID # HOW TO SET EQUAL TO INPUT?
end
My routes.rb:
Rails.application.routes.draw do
root 'static_pages#home'
get 'password_resets/new'
get 'password_resets/edit'
get 'sessions/new'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users do
member do
put 'set_wistia_project_ID'
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
end
But the problem I am having is that when I try to go to show.html.erb, my Heroku app crashes :(
The reason:
F, [2019-06-25T19:53:20.706881 #8] FATAL -- : [b2ed08bb-de52-417f-9ba8-8ec85629dce8]
app/views/users/show.html.erb:30:
syntax error, unexpected end-of-input, expecting end
But it looks fine to me?

The syntax error is that you are missing <% end %> for the <%= form_for(#user) do |f| %> block.
To answer your question about how to access the param in the model's method - you should pass it as an argument:
#user.set_project_id(params[:wistia_project_ID])
And change the method to accept an argument. Note, I am assuming you want to actually persist this to the database, so I'm adding a save call. You could alternatively call update which assigns the new value and saves in one go.
def set_project_id(val)
self.wistia_project_ID = val # self is necessary here
save # or self.save, but the self is unnecessary here
end
However, calling save does always succesfully save the record, there is still the possibility of an error if a model-level validation failed. You can handle this using flash: https://guides.rubyonrails.org/action_controller_overview.html#flash-now
or, if you don't need to redirect, can just use an instance variable to store the errors:
#user = User.find(params[:id])
#user.set_project_id(params[:wistia_project_ID])
unless #user.valid?
#errors = #user.errors.full_messages
render :show
end
and in the show view:
<% if #errors %>
<p>THE FORM COULD NOT BE SAVED </p>
<ul id='errors'>
<% #errors.each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
<% end %>
Also note, I would probably rename your set_project_id method to set_project_id! (added a bang), to signify that it mutates the input (changes its internal state).

Related

Param is missing or the value is empty - update method ruby on rails

I am working on an app for rockhounds that will allow them to track the rocks they have found. I am trying to finish a method that will allow users to update rocks. The method itself works if you go to the '/edit' page where you enter a url, but when trying to reach that page via a link from the show page for the rock I get an error:
Param is missing or the value is empty: rock
Its coming from line 43 in my rocks controller, inside the method rock_params. The parameters for this request are:
{"_method"=>"patch", "authenticity_token"=>"tiQQjQCMi6lbDPOxQ2X7fNTamWEZ3EAandGQ1Tv4NJKxieVIUnnWcKh3efd9F2LIRZWBYeC5M3RuEr0/FHQnww==", "id"=>"6"}
Here is my controller code
before_action :find_rock, only: [:show, :edit, :update, :destroy]
def index
#rocks = Rock.all
end
def show
#rock = Rock.find_by(id: params[:id])
end
def new
#rock = Rock.new
end
def create
#rock = Rock.new(rock_params)
if #rock.save
redirect_to #rock
else
render :new
end
end
def update
if #rock.update(rock_params)
redirect_to #rock
else
render :edit
end
end
def destroy
#rock = Rock.find(params[:id])
#rock.destroy
redirect_to rocks_path
end
private
def rock_params
params.require(:rock).permit(:id, :nick_name, :category, :minerals, :outcrop)
end
def find_rock
#rock = Rock.find(params[:id])
end
end ```
Here is the view code for the show page:
`<h1> Rock: </h1>
<h2> Rock Name: <%= #rock.nick_name %></h2>
<h2> Rock Type: <%= #rock.category %></h2>
<h2> Major Minerals: <%= #rock.minerals %></h2>
<h2> Outcrop? : <%= #rock.outcrop %></h2>
<%= link_to "Edit this rock", edit_rock_path(#rock), method: :patch %>
<%= link_to "Delete this rock", rock_path(#rock), method: :delete %> `
and the edit page:
```<%= form_for :rock do |f| %>
Name: <%= f.text_field :nick_name %><br>
Category: <%= f.select :category, ['Igneous', 'Sedimentary', 'Metamorphic'] %><br>
Major Minerals <%= f.text_area :minerals %><br>
Outcrop or Boulder? <%= f.select :outcrop, ['Outcrop', 'Boulder'] %><br>
<%= f.submit %>
<% end %> ```
and here are my routes:
```resources :rocks
resources :users
resources :locations
post '/users/new', to:"users#create"
get '/signup', to:"users#new", as: "signup"
post '/rocks/new', to:"rocks#create"
get '/rocks/:id/edit', to:"rocks#edit"
patch '/rocks/:id/edit', to:"rocks#update"
post '/rocks/:id/destroy', to:"rocks#destroy"
root to: "rocks#index"
get '/login', to: "auth#login", as: "login"
post '/login', to: "auth#authenticate"
get '/logout', to: "auth#logout"```
So the question is **How do I fix the empty param error that occurs when clicking the link to edit a rock from the show page for that rock?**
#toodles from the rails documentation here, edit paths are of the HTTP verb GET.
You need to change this line <%= link_to "Edit this rock", edit_rock_path(#rock), method: :patch %>, remove method: :patch which applies a PUT HTTP verb
It should look like this <%= link_to "Edit this rock", edit_rock_path(#rock) %> as rails applies the GET verb if the method is not specified.
You'll be able to see this when you inspect your link in a browser
Also, since you defined the resource :rocks, you don't need to redefine the other rock routes below it. You can see the generated routes with the rails routes command in your terminal.
You can also add an edit action to your controller, that returns #rock, which you use in the edit page. This section of the getting started with Rails article shows it clearly.

Get form data in controller rails

I'm fairly new to rails and didin't find a soloution after a lot of research...
I want to build a simple data abstaraction test app. I have a text field and a submit button and I want to do something with the input (like ie. .upcase ) and then print it out. On submit, I get a routing error, though.
What am I doing wrong?
application.html.erb
<body>
<%= form_tag("parse_input", method: "post") do %>
<%= text_field(:ans, :field) %>
<%= submit_tag("submit" %>
<% end %>
FormControllerController.rb
class FormControllerController < ApplicationController
def parse_input
params[:ans].each do |value|
puts value
end
end
end
routes.rb
Rails.application.routes.draw do
...
root :to => 'application#home'
get "application" => "form_controller_controller"
end
I don't want to use a DB btw.
Try below code:
routes.rb
Rails.application.routes.draw do
...
root :to => 'application#home'
post "parse_input" => "form_controller_controller#parse_input"
end
application.html.erb
<body>
<%= form_tag("/parse_input") do %>
<%= text_field(:ans, :field) %>
<%= submit_tag("submit") %>
<% end %>

ActionController::UrlGenerationError in Univ#index

I tried to list out the values of a specific table in the database using the following view file
index.html.erb
<%= form_tag univ_path, method: :get do %>
<p>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search", name: nil %>
</p>
<% end %>
<h1>List of Universities based on ranking</h1>
<div id="articles">
<% #univ.each do |univ| %>
<h2>
<%= link_to univ.univ_name, univ %>
</h2>
<div class="info">
<b>Location:</b> <%= univ.location %>, <%= univ.state %> <br/>
</div>
<br /><br />
<div class="content"><p><%= univ.description %><p></div>
<% end %>
</div>
and the controller file is as follows
univ_controller.rb
class UnivController < ApplicationController
def index
if params[:query].present?
#univ= Univ.search(params[:query])
else
#univ=Univ.all
end
end
def show
#univ= Univ.find(params[:id])
end
def register
#univ = Univ.new(params[:univ])
if(request.post? and #univ.save)
flash[:notice]= "Account Created Successfully"
redirect_to :controller => 'univ', :action => 'register'
end
end
end
I was able to list out the contents of the table from db. However, when I include the form_tag for implementing search it results an error
No route matches {:action=>"show", :controller=>"univ"} missing required keys: [:id]
my routes.rb has
resources :univ get 'search' => "univ#index", :as => "search"
Please suggest necessary changes
Change the form_for in index.html.erb as below:
<%= form_tag search_path, method: :get do %>
I suppose you intended to submit the form on index action using the search route defined as:
get 'search' => "univ#index", :as => "search"
for that you would have to submit the form on search_path.
You are getting the error as No route matches {:action=>"show", :controller=>"univ"} missing required keys: [:id] because currently you are submitting the form on univ_path which would route to show action and therefore require an id.
I just had this problem with a project I'm working on, and it turned out to be a Nil field in my database. Are you saving data to ruby sqlite? Check for a record that has a nil [:id] and delete that record using Model.destroy(id) and you should be able to render the page again

How to deleted nested comments in Rails

I recently did this tutorial http://www.reinteractive.net/posts/32-ruby-on-rails-3-2-blog-in-15-minutes-step-by-step, but im having trouble figuring out how to delete the comments once theyve been posted, ive tried the
method but that doesnt work as well as
it just return undefined method eror to me, what am i doing wrong
my code:
<%= div_for rep do %>
<p>
<div style="font-weight:bold; color:grey;"><%= rep.title %></div>
<div><%= rep.body %></div>
<strong style="font-size:8px;">
Posted <%= time_ago_in_words(rep.created_at) %> ago
</strong>
<br/>
<%= link_to 'Destroy', steppy_reps_path(#steppy, rep), method: :delete, data: { confirm: 'Are you sure?' } %>
</p>
<% end %>
the error:
No route matches [DELETE] "/steppies/11/reps.9"
routes.rb:
Testapp2::Application.routes.draw do
resources :steppies do
resources :reps, :only => [:create]
end
get "steppies/ask"
get "steppies/create"
get "steppy/ask"
get "steppy/create"
end
rake route output:
steppy_reps POST /steppies/:steppy_id/reps(.:format) reps#create
steppy_rep DELETE /steppies/:steppy_id/reps/:id(.:format) reps#destroy
steppies GET /steppies(.:format) steppies#index
POST /steppies(.:format) steppies#create
new_steppy GET /steppies/new(.:format) steppies#new
edit_steppy GET /steppies/:id/edit(.:format) steppies#edit
steppy GET /steppies/:id(.:format) steppies#show
PUT /steppies/:id(.:format) steppies#update
DELETE /steppies/:id(.:format) steppies#destroy
steppies_ask GET /steppies/ask(.:format) steppies#ask
teppies_create GET /steppies/create(.:format) steppies#create
steppy_ask GET /steppy/ask(.:format) steppy#ask
steppy_create GET /steppy/create(.:format) steppy#create
You need to add the action to your routes.rb file.
resources :steppies do
resources :reps, :only => [:create, :destroy]
end
Also, the form needs to use a different route.
steppy_rep_path(#steppy, rep)

Routing issue. No routes found, but I know these exist

Noob here.
Trying to figure out how to display a method in my controller into my index page. Here is what I have thus far.
Controller -
class SammichesController < ApplicationController
def index
#sammiches = Sammich.all
end
def create
#sammich = Sammich.find_by_name(params[:sammich][:name])
end
def random
#sammichy = Sammich.rand(params[:sammich][:name])
end
end
Routes-
Sammiches::Application.routes.draw do
resources :sammiches do
get "random"
end
root :to => 'sammiches#index'
Index-
<h1>All my Sammiches</h1>
<%= form_for Sammich.new do |f| %>
<%= f.label :sammich %>
<%= f.text_field :name %>
<%= f.submit 'Find Sammich', :id => 'sammich_submit' %>
<% end %>
<%= link_to "Random sandwich", sammich_random_path %>
routes-
sammich_random GET /sammiches/:sammich_id/random(.:format) sammiches#random
sammiches GET /sammiches(.:format) sammiches#index
POST /sammiches(.:format) sammiches#create
new_sammich GET /sammiches/new(.:format) sammiches#new
edit_sammich GET /sammiches/:id/edit(.:format) sammiches#edit
sammich GET /sammiches/:id(.:format) sammiches#show
PUT /sammiches/:id(.:format) sammiches#update
DELETE /sammiches/:id(.:format) sammiches#destroy
root / sammiches#index
Error-
localhost:3000 - Routing Error
No route matches {:action=>"random", :controller=>"sammiches"}
Try running rake routes for more information on available routes.
Any assistance would be much appreciated.
Thanks!
If you look at your route it has :sammic_id in there as well:
sammich_random GET /sammiches/:sammich_id/random(.:format) sammiches#random
Which means you need to pass an id to your URL helper sammich_random_path which you haven't.
Update your routes to this:
resources :sammiches do
collection do
get "random"
end
end
After adding that your route would be just /sammiches/random

Resources