sinatra-flash gem isn't working - ruby

I attempted to use the sinatra-flash gem with my application and get an "undefined local variable or method 'flash'" error when I try to run it.
my_app:
require 'sinatra/base'
require 'sinatra/flash'
class GGInfraUserManager < Sinatra::Base
enable :sessions
register Sinatra::Flash
...(rest of app)
post '/' do
flash[:error] = "Password must be a minimum of 8 characters" unless new_password.match /.{8}/
log.info "#{Time.now} password meets policy requirements"
end
redirect '/'
end
In my erb view file (at the top):
<div id="flash" class="notice">
<a class="close" data-dismiss="alert">×</a>
<%= flash.now[:error] %>
</div>
Can someone please tell me how to correct this error so that the flash functionality will work?

While the gem seems comfortable enough to use why not implement it yourself. It's in fact just a couple of lines:
#in your app.rb:
helpers do
#a partial helper
def partial(template, locals = {})
slim template, :layout => false, :locals => locals
end
#the flash helper
def flash
#flash = session.delete(:flash)
end
end
get '/' do
session[:flash] = ["Some happy news", "alert-success"]
end
Then you can add a partial view which I called partial_flash.slim
-if flash
-message, status = #flash
.alert class=(status) = message
You call that partial usually from your layout file or any other view that needs a flash message:
==partial :partial_flash
So a route is called, the layout is loaded and checks if flash. If there is, it displays a flash message with a specified class. I use Twitter Bootstrap, so alert-success is a green message box.
You can see an example app here: https://github.com/burningTyger/farhang-app

Related

How do I create a dashboard link in my Rails user controller?

I’m using Rails 5. When my user is logged in, I want to replace the ‘/users/4’ action with a generic ‘/dashboard’ home link. I would also like the remove the user’s ability to typing in ‘/users/##’ into the browser, instead only allowing them to visit ‘/dashboard’. How do I do this? Currently, in my config/routes.rb I have
get '/dashboard', to: 'users#show'
resources :users
and in my users_controller.rb file I have
def show
#user = User.find(params[:id])
#user_subscriptions = UserSubscription.find_active_subscriptions_by_user(#user)
end
But currently when I visit “/dashboard” in my browser, I get the error
Couldn't find User with 'id'=
How can I set up my route to disable the show action but allow /dashboard to successfully navigate to the action above?
What I like to do is something like this
get '/dashboard' => 'users#show', as: :dashboard
now on your view you can do
link_to 'Dashboard', dashboard_path(current_user)
and in the controller you can do
def show
params[:id] == current_user.id unless params[:id]
#user = User.find(params[:id])
#user_subscriptions = UserSubscription.find_active_subscriptions_by_user(#user)
end

Undefined Method Join-error when running CarrierWave and Sinatra.

I'm trying the Gentle Introduction to CarrierWave-tutorial by using the web-framework Sinatra. When I run my app it starts just fine and the app asks me to upload a file and it does so without any problems. However, while uploading the file, the app throws me an "undefined method `join' for # String:0x3480d50 "-error.
I've looked around a little bit on the internet and I found this issue at github where they say that the error may be due to incompatibilities between Rack and Sinatra or for having installed duplicate versions of Sinatra.
Does anybody know what's happening?
My uploader_app:
require 'carrierwave'
require 'sinatra'
require 'sqlite3'
require 'sequel'
require 'carrierwave/sequel'
DB = Sequel.sqlite
DB.create_table :uploads do
String :file
end
# uploader
class MyUploader < CarrierWave::Uploader::Base
storage :file
end
# model
class Upload < Sequel::Model
mount_uploader :file, MyUploader
end
# sinatra app
get '/' do
#uploads = Upload.all
erb :index
end
post '/' do
upload = Upload.new
upload.file = params[:image]
upload.save
redirect to('/')
end
__END__
## index
<!DOCTYPE html>
<html>
<body>
<div>
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="image" />
<input type="submit" name="submit" value="Upload" />
</form>
<% #uploads.each do |upload| %>
<img src="<%= upload.file.url %>" />
<% end %>
</div>
</body>
</html>
The error is occurring on this line in the Carrierwave Library:
path = encode_path(file.path.gsub(File.expand_path(root), ''))
It fails because root is nil, so File.expand_path(root) raises an error. I don't know why root isn't set, but the following code (that I modified from this answer) worked for me:
CarrierWave.configure do |config|
config.root = settings.root
end
I just added it to the code after declaring the Sequel class and before defining the route. Probably best to stick it in a configure block too. Note that settings.root in the code above is Sinatra's root setting.
This doesn't seem to be caused by the current problems between Rack 1.6.0 and Sinatra 1.4.5 as that's what I was running, although I'm on Ruby v2.1.2 as I mentioned in the comments above.
Depending on what you want, Sinatra's root might not be the best place to put things, as I ended up with a directory inside the project root called "uploads" which had the files in, but config.root obviously needs to be set to something.
Hope that helps.

Why "Action Mailer" is not rendering the email template?

I am using "Action Mailer" in Ruby on Rails application to send emails. I have the following action mailer:
class SecurityUserMailer < ActionMailer::Base
default from: 'myemail#gmail.com'
def password_reset(security_user)
#security_user = security_user
mail to: security_user.email, subject: 'Password Reset'
end
def email_confirmation(security_user)
#security_user = security_user
mail to: security_user.email, subject: 'Account Created'
end
end
I am successfully sending emails but the second method (email_confirmation) is not using the corresponding template.
The email templates are in views/security_users_mailer folder and named as follows:
email_confirmation.txt.erb
password_reset.txt.erb
Why only the password_reset template is used?
Note, firstly, I thought that maybe there is something wrong with the code in my template but then I replace it with text content and it is not rendered again.
Rails 4 I had this same issue, but mine was caused by having an empty layout in layouts/mailer.html.erb
The issue was caused by file extension TYPO. I have
email_confirmation.txt.erb
and a mailer template should be with extension text or html.
As you see from the official docs - the template with the same mailer action is used by default if exists.
I believe an alternative would be to specify the template you would like to render the following is an example how you may go about this
class SecurityUserMailer < ActionMailer::Base
default from: 'myemail#gmail.com'
def password_reset(security_user)
#security_user = security_user
mail to: security_user.email, subject: 'Password Reset'
end
def email_confirmation(security_user)
#security_user = security_user
mail (:to => security_user.email,
:subject => 'Account Created',
:template_path => 'email_confirmation.txt.erb',
:template_name => 'another')
end
end
Take a look at the following should provide some further insight:
Mailer Views
or look at
Api Ruby on Rails You will see example where it says Or even render a special view so that alternatively you could have inside your mail block the following:
mail (:to => security_user.email,
:subject => 'Account Created') do |format|
format.html { render 'another_template' }
format.text { render :text => 'email_confirmation.txt.erb' }
end
This should shed some light on what you are trying to accomplish

how to prevent redirect to index.html after log in or sign up?

I recently implemented a new homepage (index.html) on my rails app (into folder public/index.html) with /signin and /signup paths. Before I implemented index.html on my website, I have been redirecting users to root_url (which is home.html.erb) after sign in or sign up.
When they sign out, I've been redirecting them to root_path.
The problem is that after this new index.html, when users try to log in or sign up, they get redirected back to index.html. Is there a place to have them log in successfully to the original root_url without requiring many code edits?
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to root_path
else
flash.now[:error] = "Invalid email/password combination"
render 'new'
end
end
def destroy
sign_out
redirect_to root_path
end
end
UsersController
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome!"
redirect_to root_path
else
render 'new'
end
end
This is what I have in my routes.rb
root to: 'static_pages#home'
First off the only difference between root_url and root_path (and in general between foo_url and foo_path) is that the former is a full url (i.e. http://example.com/...) whereas the latter is just the path (the bit after the hostname). For a simple redirect they'll have the same result.
If public/index.html exists then that is where visits to '/', (i.e. root_path) will go.
If you want users to be sent to a different page after signup then change your redirect. For example if your routes file had
get '/home' => 'home#index', :as => :home
then redirecting to home_path would send people to the index action of the home controller.
The problem seems to be that your public/index.html overrides your root_path Rails route.
You cannot access the root_path if there is a file called index.html in your public directory.
You need to rename index.html to something else or use another path other than your root_path
EDIT:
Another option is to have two different erb templates for the root_path. Then in the controller action for the root_path, you could do this:
class StaticPages < ApplicationController
def home
if user_signed_in?
render 'home_signed_in'
else
render 'home_signed_out'
end
end
end
You would then need to create two erb templates at,
/app/views/static_pages/home_signed_in.html.erb
and
/app/views/static_pages/home_signed_out.html.erb
You would also need to define or replace the user_signed_in? method in my example code with your own method to detect if the user is signed in. And don't forget to remove /public/index.html
Try to change root_path with home_ControllerName_path, where ControllerName must be the name of the controller handling the home action.
go to your routes.rb file and make following change
root :to => 'main#home_page'
you can redirect to any route by modifying root: in config/routes.rb file

Rails - trying to create simple ajax example

The code below is not working for some reason. As I click at "test" it redirects me to /home/test and shows nothing.
view/home/index.html.erb
<%= link_to "test", { :controller => "home", :action => "test" }, :remote => true %>
<div id='test_div'>
</div>
view/home/index.js.erb
$("#test_div").html("some text");
controller
class HomeController < ApplicationController
def test
"test123 test456"
respond_to() do |format|
format.js {render :layout => false}
end
end
end
What should I do to refresh div_test using ajax?
What does your routes file look like? Can you post it on here? Do a rake routes and post the output.
Here are some things that may help you:
Rails documentation for routing
Also, check out the Ajax on Rails Documentation and the section on link_to_remote. The link_to_remote function is not in Rails. What version of rails are you on? Bash: $ rails -v
Look at this answer on S.O. regarding AJAX on Rails calls.
Edit: Here is another answer regarding this that may help.
Another answer on SO for updating existing element
Edit: looking over this again, I dont think you need () after respond_to or the {...} in link_to. Look at the third link. I think you need to put the page in a partial and render it. Its not rendering right now since its render :layout => false

Resources