Update
The error was that rails cant find the root_url
Visit <%= link_to root_url, root_url %> and go to your inbox for more info.
for a quick fix and I dont need to sent the user to the root_url just a notification for the user to go to the app. I change the code to this: on the mailbox email views
Visit **messages** and go to your inbox for more info.
Question
I got devise set with my rails 4 app. Im following the example mailboxer-app when I sent the message I get a error:
`error undefined local variable or method `root_url' for #<#<Class:0x007ffe0b881678>:0x007ffe0b068298>`
Stuff I have fix to get it working
Got the form sending message to user with email
user can sent and reply
mark as delete
view inbox,sentbox and trash
this are my steps
install gem -v 0.12.1
rails g mailboxer:install
run migration
use the code from the example app(controller,view,routes)
add to my user.rb acts_as_messageable and
Conversations Controller
before_filter :authenticate_user!
helper_method :mailbox, :conversation
def index
#inbox ||= current_user.mailbox.inbox.paginate(:page => params[:inbox], :per_page => 5 )
#sentbox ||= current_user.mailbox.sentbox.paginate(:page => params[:sentbox], :per_page => 5 )
#trash ||= current_user.mailbox.trash.paginate(:page => params[:trash], :per_page => 5 )
end
def create
recipient_emails = conversation_params(:recipients).split(',')
recipients = User.where(email: recipient_emails).all
conversation = current_user.
send_message(recipients, *conversation_params(:body, :subject)).conversation
redirect_to :conversations
end
form
<%= bootstrap_form_for :conversation, url: :conversations do |f| %>
<%= f.text_field :recipients%>
<%= f.text_field :subject%>
<%= f.text_field :body %>
<div class="form-actions">
<%= f.primary "send" %>
<%= submit_tag 'Cancel', type: :reset, class: 'btn btn-danger' %>
</div>
<% end %>
View
<% #inbox.each do |conversation| %>
<%= conversation.originator.username%>
<%= link_to raw(truncate(strip_tags(conversation.subject), :length => 15)), conversation_path(conversation) %>
<% end %>
Ok got the fix to this problem.
what happen is that the mailboxer mailer was looking for root_url. Rails 4.1 wont generate the views for that just copy the files from the source code and works greate.
and just change that part of the code here.
view/mailboxer/all of this files
message_mailer
notification_mailer
change this
Visit <%= link_to root_url, root_url %> and go to your inbox for more info.
to this
Visit **messages** and go to your inbox for more info.
Thanx to this guy supremebeing7. on the mailboxer issue page
Related
So I am trying to implement the password_reset functionality into my site using bcrypt. An issue I am having is the POST is going to my new action rather to my create action.
My View
<%= form_for password_resets_path, method: 'post' do %>
<div>
<h3>Please enter your email address</h3>
<%= text_field_tag :email, params[:email] %>
</div>
<div>
<%= submit_tag "Reset Password" %>
</div>
My Controller
class PasswordResetsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:email])
user.send_password_reset if user
redirect_to root_url, :notice => 'Email sent with password reset instructions.'
end
end
My Routes
resources :password_resets
And I am getting this error
ActionController::RoutingError (No route matches [POST] "/password_resets/new"):
I looked at different solutions already, and since I do not have a model the #object, would not work for me. Since I am simply just trying to call to an action.
I feel like I am missing something so very simple but for the life of me I have been unable to figure it out. Many thanks in advance to whomever is the one to help me.
Problem: <%= form_for password_resets_path, method: 'post' do %>
form_for needs an object. If you don't want an object, just use the form_tag helper:
<%= form_tag password_resets_path do %>
<%= text_field_tag :email, params[:email], placeholder: "Please enter your email address" %>
<%= submit_tag "Reset Password" %>
<% end %>
This should work for you.
I'm learning Rails by following Hartl's tutorial and making my own adjustments to it. Now, I would like to extent it and add a contact form that sends an email message. Such is not included in the tutorial, but by the end of chapter 10 we're learned to use the mailer method and we've configured SendGrid on Heroku.
I already have the view set up in the routes and think it would require the following additional steps:
1) Terminal. rails generate mailer ContactForm
2) In app/mailers/contactform.rb:
def send_contactform_email(visitor)
#visitor = visitor
mail( :to => myemail#example.com, :from => visitor.email, :subject => 'Contact form' )
end
3) app/views/contactform_mailer/ (the view for the mail message) for example:
<h1>Website contact form</h1>
<p>On <$= ... %> <%= "#{#visitor.name} (#{#visitor.email} sent the following message:" %></p>
<p><%= #visitor.message %></p>
4) app\controllers\static_pages_controller (or another location?)
# Sends contact form email.
def send_contact_form_email
ContactFormMailer.send_contactform_email(visitor).deliver_now
redirect_to contact_path, notice: 'Message sent'
end
5) app\views\static_pages\contact.html.erb (I'm not sure about the first line, should I also do something in the routes.rb? My guess is this first line will have to tell to execute the method in step 4, which is not going to work the way it is now.)
<%= form_for(:static_pages, url: contactform_path) do |f| %>
<i class="pt-row-icon glyphicon glyphicon-user"></i> <%= f.label :name %>
<%= f.text_field :name, placeholder: 'Name', class: 'form-control' %>
<i class="pt-row-icon glyphicon glyphicon-envelope"></i> <%= f.label :email %>
<%= f.email_field :email, placeholder: 'Email', class: 'form-control' %>
<i class="pt-row-icon glyphicon glyphicon-envelope"></i> <%= f.label :message %>
<%= f.text_area :message, placeholder: 'Your messageā¦', class: 'form-control' %>
<%= f.submit "Send", class: "btn btn-primary" %>
<% end %>
I don't think this is 100% correct yet, particularly the bold sections. What are your thoughts?
UPDATE, VERSION 2: I've tried to make the updates as suggested by Ven and now have the code below. The idea as I understand it is that
the controller in def contact sets the #message variable.
the form_for knows it should fill this variable with params[:message].
the controller adopts the values from the form_for and passes them to the mailer.
the mailer uses the mailer view to design the message to be sent.
the mailer sends it back to the controller that send the message.
1) App/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
before_action :valid_email?, only: [:send_message_email]
# Shows the contact form page
def contact
#message = message(message_params)
end
# Sends the message.
def send_message_email
#message = message(message_params)
if #message.valid?
MessageMailer.new_message(#message).deliver_now
redirect_to contact_path, notice: "Your messages has been sent."
else
flash[:alert] = "An error occurred while delivering this message."
render :new
end
end
private
def message_params
params.require(:message).require(:name, :email, :content)
end
def valid_email?(email)
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
email.present? && (email =~ VALID_EMAIL_REGEX)
end
end
2) Contact form in app\views\static_pages\contact.html.erb:
<%= form_for(message: params[:message], url: contact_path) do |f| %>
<%= f.label :name %> <%= f.text_field :name, placeholder: 'Name', class: 'form-control' %>
<%= f.label :email %> <%= f.email_field :email, placeholder: 'Email', class: 'form-control' %>
<%= f.label :content %> <%= f.text_area :content, placeholder: 'Your messageā¦', class: 'form-control' %>
<%= f.submit "Send", class: "btn btn-primary" %>
<% end %>
3) Routes.rb
get 'contact' => 'static_pages#contact', as: 'contact'
post 'contact' => 'static_pages#send_message_email'
4) App/views/message_mailer.text.erb (and html.erb)
<%= #message[:name] %> <%= #message[:email] %> wrote:
<%= #message[:content] %>
5) App/mailers/message_mailer.rb
class MessageMailer < ApplicationMailer
default to: "myemail#example.com>"
def new_message(message)
#message = message
mail to: "myemail#example.com"
mail from: #message[:email]
mail subject: "Message from #{message[:name]}"
end
end
Now when I try to visit the contact form on the server, I get the error message: param is missing or the value is empty: message. It refers to the params.require(:message).require(:name, :email, :content) line. Not sure what I'm doing wrong. Changing it to params.require(:message).permit(:name, :email, :content) makes no difference.
4) app\controllers\static_pages_controller (or another location?)
This seems to be correct, if this is the github repo for said app.
def send_contact_form_email
You controller has an issue: this action will try to send the email, not matter if it's used in POST or GET. You should use two different actions, one for displaying the view (using GET), and one for sending the email (using the mailer class you created). (at this point, you might want to create another controller)
ContactFormMailer.send_contactform_email(visitor).deliver_now
Then, moving on: what you pass to your mailer is "visitor". There's no such variable.
You probably want to access something out of the params hash (which contains parameters for GET and POST requests), and use the same key as your form (form_for(:visitor ... => params[:visitor] (so you want to change that :static_pages)).
<p>On <$= ... %> <%= "#{#visitor.name} (#{#visitor.email} sent the following message:" %></p>
As this returns an object, and not a hash, #visitor.email needs to be #visitor[:email] inside the mailer.
One last thing: simply using params[:visitor] will mean people could leave the field blanks. You might want to look into strong parameters, that were added in Rails 4 (the book seems somewhat outdated?).
And lastly, you need to add routes to be able to reach these actions (one for the GET request - display the view - and one for the POST request - to submit the form).
PS:
mail( :to => myemail#example.com, :from => visitor.email, :subject => 'Contact form' )
Warning: here, you forgot to quote the email address. Also, you swapped the to/from parameters. You want to send TO your visitor email, not from it.
EDIT
params.require(:message).require(:name, :email, :content)
This will require said keys, but AFAIK on the same "level" as :message - the top one. You want to use permit:
params.require(:message) # require "namespace"
.permit(:name, :email, :content) # permit keys
#message = message(message_params)
Where is the message function defined?
mail to: "myemail#example.com"
mail from: #message[:email]
mail subject: "Message from #{message[:name]}"
This sends 3 different emails, since you called the mail function 3 times.
I have installed the mailboxer gem to my rails app. It's successfully working when i'm using it in the console.
Exemple: current_user.send_message(User.last, "Body", "subject")
But i want to know how to do to make it work with a form view and a controller.
I want to be able to pass the send_message arguments through a view and send it to a message or a conversation controller.
I don't know the right way to handle this fantastic gem.
Thanks in advance
J.D.
The controller to send a message from a form:
class MessageController
# GET /message/new
def new
# display form
end
# POST /message/create
def create
recipient = User.find(params[:recipient_id])
current_user.send_message(recipient, params[:body], params[:subject])
end
end
Form view:
<%= form_tag({controller: "messages", action: "create"}, method: :post) do %>
<%= text_field_tag :subject %>
<%= text_area_tag :body %>
<%= submit_tag 'Send email' %>
<% end %>
A field for the recipient is missing in this example.
you need to have the basic knowledge in Actionmailer in rails take a look at the actionmailer
link:
guides.rubyonrails.org/action_mailer_basics.html
I've seen this question asked everywhere, but it never solves my problem. Heres my controller:
class UserVacationDaysController < ApplicationController
def new
#user = current_user
#user_vacation_days = UserVacationDay.new
end
def create
#user_vacation_days = UserVacationDay.create(params[:user_vacation_day])
#user_vacation_days.user = current_user
# #user_vacation_days.calculate_work_days
# (another param that holds date range will get passed in)
# puts #user_vacation_days.errors.inspect
if #user_vacation_days.persisted?
flash[:notice] = "Request Sent"
redirect_to dashboard_index_path
request_vacation_days # method from model. model method calls method in employee_mailer
else
flash[:notice] = "Something went wrong, please try again"
render :new
end
end
end
And here is my view (form).
<h2>Request Days Off</h2>
<%= form_for :user_vacation_days, :url => user_vacation_days_path do |f| %>
<div><%= f.label "How much time off would you like to take?" %>
<%= f.number_field :number_of_days %></div>
<div><%= f.label "Argue your case, slave" %>
<%= f.text_area :description %></div>
<div><%= f.submit "Request Time Off" %></div>
<% end %>
The routes for my 2 controller methods are
user_vacation_days POST /user_vacation_days(.:format) user_vacation_days#create
new_user_vacation_day GET /user_vacation_days/new(.:format) user_vacation_days#new
Does anyone have any idea what's going on? I've looked all over the place, and I can't find anything. I can't think of any reason why the controller method wouldn't be found. Thanks!
Instead of <%= form_for :user_vacation_days, :url => user_vacation_days_path do |f| %> what happens if you use <%= form_for #user_vacation_days, :url => user_vacation_days_path do |f| %>
Also, does a User have_many VacationDay? You might want to change to resourceful routes, and have vacation days nested.
config/routes.rb
resources :users do
resources :user_vacation_days
end
in your new action under UserVacationDaysContoller #may want to rename this to just VacationDays since the nesting implies
def new
#user = current_user
#user_vacation_days = #user.vacation_days.build
end
I have what seems to be a non-standard signup process:
[welcome! enter your email and password] => [cool, enter a lot more information] => [registered]
I'm having trouble getting rails to recognize that I want to validate only the email and password on page 1, and all the other stuff on page 2.
When the user hits the site, they see my welcome page:
class WelcomeController < ApplicationController
def index
#user = User.new
end
end
<%= form_for(#user) do %>
<div class="formItem">
<%= label_tag(:email, "Your email address:") %>
<%= text_field(:user, :email) %>
<br clear="all" />
</div>
<div class="formItem">
<%= label_tag(:password, "Select a password:") %>
<%= password_field_tag(:password) %>
<br clear="all" />
</div>
<%= submit_tag("Sign up today - it's free and easy!", :class => "submitForm") %>
<% end %>
=
class UsersController < ApplicationController
def create
#user = User.new(params[:user])
if #user.save
redirect_to(edit_user_path(#user, :noticeHeader => true ), :notice => 'Please take a minute and answer these additional questions.')
else
render :action => "welcome/index"
end
end
=
Once they click Sign Up, they see my next page of form fields.
The problem I'm running into is that I validates_presence_of fields that are on both pages, in the user model. Since these fields aren't on the welcome page, I get a "undefined local variable or method" error upon submitting the welcome page. For example, I validates_presence_of :title because I want title to be required, but it's only listed on page 2, so page 1 doesn't validate properly.
Thoughts on how to handle this?
Thanks.
Have a look into one of these plugins/gems where you can create Wizard based forms.
http://ruby-toolbox.com/categories/rails_wizards.html my favourite is "ActsAsWizard"