I've been looking for a bit and can't find or rather very well understand what to do, I'm sure its quite simple I'm just very new to Ruby and web apps, this one is in Sinatra for simplicity. I'd like to pass the #multiplication_table variable as well as the things the user puts into the inputs to the next results page so I can see if they put in the answers correctly but dont know how to, I think I know how to do this with a form_for but I dont know how to do that with already having a for loop.
This is my web.rb file
# web.rb
require 'sinatra'
def create_table(number)
possibles = [1,2,3,4,5,6,7,8,9,10,11,12]
int_set = possibles.shuffle
result = []
#answer_list = []
while int_set.length > 0
random_int = int_set[0]
string = (number.to_s + " x " + random_int.to_s)
int_set.delete(random_int)
if (random_int.to_s).length == 1
string += " = ______"
else
string += " = ______"
end
result << string
#answer_list << random_int.to_i * number.to_i
end
return result
end
get '/' do
#greeting = "Hi! Enter a number to generate a quick test."
erb :index
end
post '/results' do
erb :results
#multiplication_table
end
post '/' do
#multiplication_table = create_table(params[:int_to_generate])
#answers = #answer_list
erb :multiplication_table_page
end
and this is my multiplication_table_page.erb
<!-- multiplication_table_page.erb -->
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.3/css/bootstrap.min.css">
</head>
<style>
h1 {text-align:center;}
p {text-align:center;}
.form-group {float: right; width: 100%;}
input {float: right;}
#submitall{width:100%;}
</style>
<body>
<div class="container">
<h1>Here is your table! Good luck.</h1>
<form action ="/results" method="POST" class="form-inline">
<% counter = 0 %>
<% #multiplication_table.each do |equation| %>
<input type="text" name = <%= "user_answer" + counter.to_s %> class="form-control">
<h2> <%= equation %> </h2>
<% counter += 1 %>
<% end %>
<p> </p>
<input id=submitall type="submit" class = "btn btn-primary">
</form>
<p> </p>
<p>Put another number in for another table</p>
<form action ="/" method="POST" class="form-inline">
<div class = "form-group">
<input type="submit" class = "btn btn-primary">
<input type="text" name ="int_to_generate" class="form-control">
</div>
</form>
<% #answers.each do |answer| %>
<p> <%= answer %> </p>
<% end %>
</div>
</body>
</html>
Related
I implemented a RoR mailer with my Ruby on Rails Application and it worked well. But to my surprise, every time a mail is sent, other attributes from my database table is populated in my sent email which I do not want.
To have a diagramatic view of my problem, see this Mailer Preview image:
model(job.rb)
class Job < ActiveRecord::Base
def self.jobs_posted_12hrs_ago
where.not('stripeEmail' => nil).where.not('payola_sale_guid' => nil).where('created_at > ?', Time.now - 12.hours)
end
end
app/mailer/job_notifier.rb
class JobNotifier < ApplicationMailer
def send_post_email(job)
#user = User.where(:email => true).all
emails = #user.collect(&:email).join("#{';'}")
#jobs = job
#job = job
mail(:to => emails, :bcc => User.pluck(:email).uniq, :subject => 'New job posted on FarFlungJobs')
end
end
email template/view(send_post_email.html.erb)
I did iterate over my scope and populated just Comapny Name, Job Title, and Date. but when the email is previewed/sent, other attributes in the database are populated with it.
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<div>
<h3> Hi, new job just posted on FarFlungJobs.com! </h3>
</div>
<section>
<p>Fresh Job</p>
<hr>
<p>
<% jobs = Job.jobs_posted_12hrs_ago %>
<%= jobs.each do |job| %>
<section class="container">
<div class="row jobs">
<div class="col-md-4" style="font-size: 20px;"><strong><%= job.company_name %></strong></div>
<div class="col-md-4" style="font-size: 20px;"><%= link_to(job.title, job) %></div>
<div class="col-md-4 text-right" style="font-size: 20px; float: left;"><%= job.created_at.strftime('%d %B %y') %></div>
</div>
<%= render 'shared/two_breaks'%>
</section>
<% end %>
</p>
<p>Thanks for subscribing to FarFlungJobs once again. <%= jobs_url %> </p>
</section>
</body>
</html>
What can I do to make sure I only have just the specified attributes in my email template being sent, instead of it add all I dont want?
The problem is this line:
<%= jobs.each do |job| %>
Because of the <%= it will print out the result of the each statement, which is jobs.
I have a Rails 4.2 app in which I'm using Ransack mixed with Geocoder for search. I want to use an Ajax (remote: true) for my search to avoid pageloads and changing of the URL.
When I implement this in my index view it works great, but I want to abstract the search box to the application layout file so it's available site wide instead of just on the index view. When I do this (see code example) I'm able to search just fine, but the problem is I can't seem to figure out how to get the Ajax/Remote: True to work. Here is my code:
application.html.erb
<%= search_form_for(#search, url:"/resources", :method => :get, remote: true) do |f| %>
<%= text_field_tag :location, params[:location], placeholder: "Houston, TX", class: "input-sm form-control" %>
<%= f.submit "Find", class:'btn btn-sm btn-info' %>
<% end %>
application_controller.rb
before_action :build_search
private
def build_search
if params[:location].present?
#search = Resource.near(params[:location], 100).search(params[:q])
else
#search = Resource.search(params[:q])
end
end
resources/index.js.erb
$("#mapdisplay").html("<%= escape_javascript render("map") %>");
$("#results").html("<%= escape_javascript render("results") %>");
resources/index.html.erb
<div id="mapdisplay">
<%= render 'map' %>
</div>
<div id="results">
<%= render 'results' %>
</div>
resources_controller.rb
before_action :set_search_results, only: [:show, :index, :new]
def index
#hash = Gmaps4rails.build_markers(#resources) do |resource, marker|
marker.lat resource.latitude
marker.lng resource.longitude
end
respond_to do |format|
format.html {}
format.js {}
end
end
private
def set_search_results
#resources = #search.result(distinct: true)
end
resources/_map.html.erb
<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
<script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js' type='text/javascript'></script>
<h4>Resources</h4>
<div id="search">
<%= render 'search' %>
</div>
<div class="pull-right">
<%= link_to "Add", new_resource_path, class: 'btn btn-info btn-medium' %>
</div>
<div style='width: 800px;'>
<div id="map" style='width: 800px; height: 400px;'></div>
</div>
<script>
handler = Gmaps.build('Google');
handler.buildMap({
provider: {
disableDefaultUI: true
// pass in other Google Maps API options here
},
internal: {
id: 'map'
}
},
function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
}
);
</script>
resources/_search.html.erb
<div class="form-group">
<%= search_form_for(#search, :id => "resource_search", remote: true) do |f| %>
<%= text_field_tag :location, params[:location], placeholder: "Houston, TX", class: "input-sm form-control" %>
<%= f.submit "Find", class:'btn btn-sm btn-info' %>
<% end %>
</div>
resources/_results.html.erb
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<% #resources.each do |r| %>
<tr>
<td><%= link_to "#{r.name}", r %></td><td><%= r.address %></td><td><%= r.notes %></td>
</tr>
<% end %>
</tbody>
</table>
Again, I can get this working in the index view/controller with js and remote: true but when I implement the search box sitewide in the application layout file I cannot use JS/remote: true.
I'm sure I'm missing something simple in my implementation so if anyone has any advice, please let me know. If my question and/or code examples are not clear let me know and I'll explain in further detail.
I'm using an example from Eric London http://ericlondon.com/2014/03/13/rails-4-submit-modal-form-via-ajax-and-render-js-response-as-table-row.html
And have adapted it slightly to my scenario:
While editing a Team (model) I want to pop a modal form to Add a new User. I can get this working i.e. when all fields are correct, the record is saved and the modal closes, but I am not getting errors back into the modal when there is a problem.
I also am uncertain how to structure the Create controller action correctly - this is definitely not right.
In the Users controller, create action (below) I can save the record as I expect, I have commented out the original code (I still need this - its the defaults for normal user management)
def create
#if params[:modal].nil? || params[:modal] == ''
# create! { users_url }
#else
respond_to do |format|
password = Devise.friendly_token.first(6)
#user.password = password
#user.password_confirmation = password
#user.external = true
if #user.save!
format.js { render action: 'show', status: :created, location: #user }
else
format.js { render json: #user.errors, status: :unprocessable_entity }
end
end
#end
end
the show.js.erb view
$('#new_user_modal').modal_success();
and the application.js code:
$(document).ready(function(){
$(document).bind('ajaxError', 'form#new_user', function(event, jqxhr, settings, exception){
// note: jqxhr.responseJSON undefined, parsing responseText instead
$(event.data).render_form_errors( $.parseJSON(jqxhr.responseText) );
});
});
(function($) {
$.fn.modal_success = function(){
// close modal
this.modal('hide');
// clear form input elements
// todo/note: handle textarea, select, etc
this.find('form input[type="text"]').val('');
// clear error state
this.clear_previous_errors();
};
$.fn.render_form_errors = function(errors){
$form = this;
this.clear_previous_errors();
model = this.data('model');
// show error messages in input form-group help-block
$.each(errors, function(field, messages){
$input = $('input[name="' + model + '[' + field + ']"]');
$input.closest('.form-group').addClass('has-error').find('.help-block').html( messages.join(' & ') );
});
};
$.fn.clear_previous_errors = function(){
$('.form-group.has-error', this).each(function(){
$('.help-block', $(this)).html('');
$(this).removeClass('has-error');
});
}
}(jQuery));
in the teams form I have the link and the modal definition:
<%# Added Bootstrap data modal attribute %>
<%= link_to 'Add an External User', '#new_user_modal', 'data-toggle' => 'modal', class: 'btn btn-default' %>
<%# Bootstrap modal markup. #see: http://getbootstrap.com/javascript/#modals %>
<div class="modal fade" id="new_user_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Create new User</h4>
</div>
<div class="modal-body">
<%# Render the new person form (passing modal => true to enable remote => true) %>
<%= render 'users/new', modal: true %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
in the users/_new.html.erb view I have:
<% #user = User.new %>
<%= simple_form_for #user, remote: true, input_html: {role: :form, 'data-model' => 'user'} do |f| -%>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<!-- username -->
<%= f.input :remote_id, label: "Payroll Code / Username" %>
<!-- basic settings -->
<div class="row">
<div class="col-md-6">
<%= f.input :first_name %>
</div>
<div class="col-md-6">
<%= f.input :last_name %>
</div>
</div>
<%= f.input :email %>
</fieldset>
<div class="actions">
<%= f.submit 'Submit', class: 'btn btn-primary' %>
</div>
<% end -%>
So, to sum up where I am at:
I want to add new users from a modal form while editing another
model
The approach above mostly works...
But is heinously ugly - it
feels wrong/messy and I am not happy with it.
It seems you don't have any 'help-block' classes on your form.
Try:
$.each(errors, function(field, messages){
$input = $('input[name="' + model + '[' + field + ']"]');
$span_error = $("<span></span>").addClass('help-block').html( messages.join(' & ') );
$form_input = $input.closest('.form-group').addClass('has-error').find('.form-control');
$span_error.insertAfter($form_input);
});
Instead of:
// show error messages in input form-group help-block
$.each(errors, function(field, messages){
$input = $('input[name="' + model + '[' + field + ']"]');
$input.closest('.form-group').addClass('has-error').find('.help-block').html( messages.join(' & ') );
});
I'm using sequel.
In my app.rb, I wrote
get '/search' do
#post = Post.find(:Title => "%#{params[:query]}%")
erb :'layout'
end
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 %>
And to the blog_model.rb in post class this:
def self.search(query)
#where(:title, query) -> This would return an exact match of the query
where("title like ?", "%#{query}%")
end
And I'm getting this :LocalJumpError at /search
no block given (yield).
So what to do or have I done this code correctly ? Thanks in advance.
I guess the problem is the name of erb file, layout.erb.
Sinatra always search for a layout.erb, if you not explicit indicate other layout file, that will handle the page template. This file has the form:
<!doctype html>
<html>
<head>
...
<body>
...
<%= yield %> insert the content here
...
</html>
There are two solutions:
Rename the layout.erb file.
Replace the erb call by: erb :layout, layout: false
So, I'm new to Ruby/Sinatra, did a bunch of codecademy lessons and the like. I decided until I actually built something, I wouldn't really understand some core concepts.
I found a tutorial for building a to-do list app in Sinatra, and all was fine and good until I got to the edit and delete functionality. I can read and write to/from the database, but whenever I try to edit or delete, it skips straight to "Note not found".
I couldn't figure this out myself, so I asked a developer friend of mine. When I sent him the code, everything worked absolutely fine for him! We tried a couple of different possible fixes, but to no end. I even downloaded the code from the guy's github, just in case there was a random mistake somewhere in my own code, to no avail.
So, I come here asking for some help! Why won't this work!
Clarification: Here's some of the code, where I think the problem may lie. In edit.erb and delete.erb, no matter what it is going to the else statement and sending me to "note not found". It's reading properly from the database, as my homepage can add and show notes.
recall.rb
get '/:id' do
#note = Note.get params[:id]
#title = "Edit note ##{params[:id]}"
erb :edit
end
put '/:id' do
n = Note.get params[:id]
n.content = params[:content]
n.complete = params[:complete] ? 1 : 0
n.updated_at = Time.now
n.save
redirect '/'
end
get '/:id/delete' do
#note = Note.get params[:id]
#title = "Confirm deletion of note ##{params[:id]}"
erb :delete
end
delete '/:id' do
n = Note.get params[:id]
n.destroy!
redirect '/'
end
edit.erb
<% if #note %>
<form action="/<%= #note.id %>" method="post" id="edit">
<input type="hidden" name="_method" value="put">
<textarea name="content"><%= #note.content %></textarea>
<input type="checkbox" name="complete" <%= "checked" if #note.complete %>>
<input type="submit">
</form>
<p>Delete</p>
<% else %>
<p>Note not found.</p>
<% end %>
delete.erb
<% if #note %>
<p>Are you sure you want to delete the following note: <em>"<%= #note.content %>"</em>?</p>
<form action="/<%= #note.id %>" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="Yes, Delete It!">
Cancel
</form>
<% else %>
<p>Note not found.</p>
<% end %>
Moving the delete-route above the other routes seemed to work for me, which would suggest that the /:id -part in the route definition catches the /delete-part as well. You can see the generated regexps with Sinatra::Application.routes.
Here's a minimal:
require 'rubygems'
require 'sinatra'
require 'dm-core'
require 'dm-migrations'
require 'dm-sweatshop'
# Models
DataMapper.setup(:default, 'sqlite::memory:')
class Note
include DataMapper::Resource
property :id, Serial
property :content, Text, :required => true
property :complete, Boolean, :default => false
property :created_at, DateTime, :default => lambda {Time.now}
property :updated_at, DateTime
before(:save) { attribute_set(:updated_at, Time.now) }
end
DataMapper.finalize.auto_migrate!
# Fixtures
Note.fix {{
:content => /\w+/.gen
}}
100.of { Note.gen }
# Routes
before("/:id") {|id| #note = Note.get id }
get("/:id/delete") {|id| #note = Note.get id; erb :delete }
get("/:id") { erb :edit }
put "/:id" do
#note.attributes = params["note"]
#note.save ? redirect(to("/")) : erb(:edit)
end
delete("/:id") { #note.destroy; redirect(to("/")) }
# Templates
template :layout do
'<!DOCTYPE html>
<html>
<body><%= yield %></body>
</html>'
end
template :edit do
'<% if #note %>
<form action="/<%= #note.id %>" method="POST">
<input type="hidden" name="_method" value="PUT">
<textarea name="note[content]"><%= #note.content %></textarea>
<input type="checkbox" name="note[complete]"
<%= #note.complete? && "checked" %> >
<input type="submit">
</form>
<p>Delete</p>
<% else %>
<p>Note not found.</p>
<% end %>'
end
template :delete do
'<% if #note %>
<p>Are you sure you want to delete the following note:
<em>"<%= #note.content %>"</em>?</p>
<form action="/<%= #note.id %>" method="POST">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="Yes, Delete it!">
Cancel
</form>
<% else %>
<p>Note not found</p>
<% end %>'
end
I don't know if this is still interesting someone, but a simple
params[:id].to_i
fixed it for me.