Sinatra HTTP 'PUT' method - ruby

Something's wrong with the PUT action here, the form gets processed but the updated field is not being saved.
I've did what Sinatra users are doing, by adding in "_method" for Sinatra to recognise that's its a HTTP PUT action. Could anyone spot any mistake here?
# edit
get '/entries/*/:id/edit' do
#entry = Entries.get(params[:id])
#title = "edit"
erb :edit, :layout => :edit_layout
end
# update
put '/entries/:id' do
#entry = Entries.get(params[:id])
if #entry.save
redirect "/entries/id=#{#entry.id}"
else
redirect "/enewsletters"
end
end
<!-- Edit form -->
<form action="/enewsletters/edit/<%= #entry.id %>" method="post">
<input name="_method" value="put" type="hidden"/>
<p>
<label>Content</label><br/>
<input type="text" name="entry[title]" value="<%= #enew.title %>">
</p>
<p>
<input type="submit" name="commit" value="update">
</p>
</form>

You don't seem to be doing any update to the #entry, you're just fetching the specific entry with the id from params. Are you using ActiveRecord? If so, instead of #entry.save, try #entry.update_attributes(params[:entry]).
Edit: I'm guessing you're not using AR since I just noticed the .get call. Whatever ORM you are using must have an easy way to update the attributes and then save the record.

Related

Form Does not update database sinatra

I am facing issues with the connection of a form with the database, when I am trying to update a record using Sinatra.
I created a route and a form in a view.
At first the form connects to the get route and brings the relevant data. However, when I modify the fields and press the submit button to update the database, the record does not updated.
get'/users/:id/edit'do
# see the User we want to edit
#user = User.find_by_id(params[:id])
#Assign the values to all properties
#user.username = #user.username
#user.password = #user.password
#user.description =#user.description
#user.city = #user.city
#user.save
erb:edit
end
put 'users/:id/edit' do
#user = User.find_by_id(params[:id])
#Assign the values to all properties
#user.username = #user.username
#user.password = #user.password
#user.description =#user.description
#user.city = #user.city
#user.save
end
My form looks like this:
<form action="users/:id/edit" method="post" id="edit">
<input type="hidden" name="_method" value="put">
User ID : :<%=#user.id%> <br>
Username:<input type="text" name="username" value=
<%=#user.username%>"><br>
Password:<input type="password" name="password" value="
<%=#user.password%>"><br>
City:<input type="text" name="city" value="<%=#user.city%>">
<br>
Tell us more about you:<input type="text" name="description"
value="<%=#user.description%>"><br>
<input type="submit" name="Update" class="btn btn-primary " >
</form>
Can you please assist?
The form was passing the record id to the route, thus I modified the form to:
<form action="/users/edit/<%=#user.id%>" method="post"
id="edit">
and the route to:
put '/users/edit/:id' do
#user = User.find_by_id(params[:id])
#user.city= params[:city]
# rest of the fields need to be modified
end

patch method in ruby sinatra

I'm writing a web app using sinatra and activerecord but I can't figure it out what's wrong into my code...if you could just check it and guide me through it would be awesome !!All the models are linked but I can't update information about some books into the database..
RUBY SINATRA CODE :
get '/info/:isbn/edit' do
#book = Book.find_by(isbn: params[:isbn])
erb :edit
end
patch '/info/:isbn' do
book = Book.find_by(isbn: params[:isbn])
book.title = params[:title]
book.page_count = params[:number_pages]
book.category = params[:category]
book.save
redirect to "/info/#{ params[:isbn] }"
end
ERB PAGE
<form action="/info/<%= #book_isbn%>/edit" method="post">
<input type="hidden" value="patch" name="_method">
<label for="">Title</label>
<input type="text" name="title" value="<%= #book_title %>">
</form>
and this is the error page...
Check to make sure that your controller sets :method_override to true.
set :method_override, true
Without it Sinatra won't know what do with input type="hidden" value="patch" name="_method"
You are sending your form to the wrong URL:
<form action="/info/<%= #book_isbn%>/edit" method="post">
URL should be /info/<%= #book_isbn%>.

How do I pass an existing Variable that changes at refresh to a param in a post method using sinatra

I'm using sinatra as my web framework and right now I have
<p><%= #sentence %></p>
<form action='/' method='POST'>
<button type='submit'>Save Story</button>
</form>
in my erb file. The variable at #sentence changes at refresh. When I hit the save Story button I want it to create a param in the post method that is equal to #sentence so that I can save #sentence to the main page. Is there anyway to do this without javascript?
ANSWERED
I used
`<div class="row">
<form action='/' method='POST'>
<input id="sentence" type="hidden" name="sentence" value= "<%= #sentence %>" >
<button type='submit'>Save Story</button>
</form>
</div>`
its still only taking the first word on one of the 4 pages but there must be something else going on there.
You need to create a hidden input field with the value set to w.e #sentence is
<p><%= #sentence %></p>
<form action='/' method='POST'>
<input type="hidden" name="sentence" value="<%= #sentence %>" />
<button type='submit'>Save Story</button>
</form>
This will give the form something to pass that you can grab with post elsewhere, hope that helps, just put your variable where the ... is and be sure to tell it the language, here is a php example on how to add a varaible to a value.
value="<?php echo $state; ?>"
Here I'm basically telling the browser to echo(print) the state variable between the " and " using php start and end to initiate the language and end it, The hidden type input field is invisible to users and they cannot edit it, its a background trick you can use to pass information, it acts as a text field.
Information on hidden fields:
http://www.blooberry.com/indexdot/html/tagpages/i/inputhidden.htm
When you select an answer, please edit your main post to display ANSWERED and the updated code so users can see what you decide to use.
In sinatra you can do this:
<p><%= #sentence %></p>
<form action='/' method='POST'>
<input type="hidden" name="sentence" value="<%= #sentence %>" />
<button type='submit'>Save Story</button>
</form>

Getting no results back from a form_for in Rails 4.0 Ruby 2.0

I am attempting to make a quiz in my rails application and I have looked around and the only gem out there that looked like it did what I want was Survey, but that is not ready for rails 4. Anyway I borrowed the structure that Survey gem creates. So I have Attempts, Surveys, Questions, and Answers
My problem is when I try to pass back which answers were picked to the attempt controller and I am not sure. I am still new to rails so it could be something I am doing / not doing.
The View looks like this
<% provide(:title, 'Quiz') %>
<h1>Quiz</h1>
<%= form_for(Attempt.new) do |f| %>
<% #survey = Survey.find(1) %>
<h3><%= #survey.description %></h3>
<br/>
<% #survey.questions.each do |question| %>
<h4><%= question.text %></h4>
<br/>
<% question.answers.each do |answer| %>
<h5><%= f.radio_button question, answer.correct?, :checked => false %> <%=answer.text%></h5>
<br/>
<% end %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The Params currently being returned are
{"utf8"=>"✓", "authenticity_token"=>"yCp4rsZfgZDTYK32FYgXTyZSQRQ4DcTWfokbrhImI1Q=", "attempt"=>{}, "commit"=>"Create Attempt", "action"=>"create", "controller"=>"attempts"}
This is my model structure (Grouped together to make it easier to read)
Attempt has many Surveys
Survey belongs to Attempts
Survey has many Questions
Question belongs to Surveys
Question has many Answers
Answer belongs to Questions
Edited: Added in form html
<form accept-charset="UTF-8" action="/attempts" class="new_attempt" id="new_attempt" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"><input name="authenticity_token" type="hidden" value="jOQCSERK6LKWwKwIprv0fhn62W+9T13WSXss8oswyFo="></div>
<h3>Tests if I can register individuals</h3>
<br>
<h4>Paul's Favorite Color</h4>
<br>
<h5><input id="attempt_#<Question:0x007f41704d11e8>_false" name="attempt[#<Question:0x007f41704d11e8>]" type="radio" value="false"> Green</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d11e8>_false" name="attempt[#<Question:0x007f41704d11e8>]" type="radio" value="false"> Blue</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d11e8>_true" name="attempt[#<Question:0x007f41704d11e8>]" type="radio" value="true"> Teal</h5>
<br>
<h4>Paul's Age</h4>
<br>
<h5><input id="attempt_#<Question:0x007f41704d0b80>_false" name="attempt[#<Question:0x007f41704d0b80>]" type="radio" value="false"> 20</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d0b80>_true" name="attempt[#<Question:0x007f41704d0b80>]" type="radio" value="true"> 21</h5>
<br>
<h5><input id="attempt_#<Question:0x007f41704d0b80>_false" name="attempt[#<Question:0x007f41704d0b80>]" type="radio" value="false"> 22</h5>
<br>
<div class="actions">
<input name="commit" type="submit" value="Create Attempt">
</div>
</form>
Create an Attempt instance variable in AttemptsConroller on creation:
def new
#attempt = Attempt.new
end
In your view use the instance just created:
<%= form_for(#attempt) do |f| %>
That should do the trick if I did not completely miss the problem at hand.
The HTML you posted really makes it clear that something "un-railsish" is going on here. If you call the form_for-helper method in the way you did it it will create a FormBuilder object which will build the actual form, so we have to check the parameters of the radio_button in the FormBuilder class (in Rubyspeak that might also be FormBuilder#radio_button). There we find
radio_button(method, tag_value, options = {})
so the three parameters of the method rails expects are the name of the method of the object the form should operate on (which in your case would be your Attempt.new object). The most usual thing to pass at this point is a symbol with the method name, but as you provided a Question-object rails is trying to be forgiving and converts whatever it is passed into a String (probably using the to_s method). As you do not seem to have implemented to_s in your Question class the default implementation of Object will kick in to provide a "description" of your object with a class name and an address in angular brackets. As the angular brackets would confuse the HTML-parser these are gently escaped for you and you end up with messed up id and name attributes of your input elements. This will most certainly confuse the rails params parser when the HTTP POST-request is passed back and you end up with what you posted.
It is not really obvious how to fix this without knowing more about your Model classes, but most probably you want to use a nested form to solve this in the right way. This is not something I can do from the top of my head, but you can check out this RailsCast for more info.

How do I create a search form for my posts with Sinatra and Sequel?

I am new to Ruby, and am using Sinatra and Sequel. I'm trying to implement a form to search through the title of my posts.
I'm doing this in my controller:
post '/search' do
#post = Post.all(:Title.like => "%#{params[:query]}%")
erb :layout
end
And I'm doing this in my layout.erb:
<form action="/search" method="get">
<input type="text" name="query"/><br />
<input type="submit" />
</form>
<% if #results %>
<table>
<%#results.each do |r|%>
<tr valign="top">
<td><%=r.Title%></td>
</tr>
<%end%>
</table>
<% end %>
When I submit, this is the URL I get directed to:
http://localhost:4567/search?query=post
but it displays the "Sinatra doesn't know this ditty." screen.
What am I missing here?
Your form is doing a HTTP GET
<form action="/search" method="get">
but your Sinatra action is defined to receive HTTP POST requests.
post '/search' do
I think what is confusing you is that you have a class named Post. The get and post in the actions are not class names, but REST actions. Review routing.

Resources