I am working on a rails application and want to send an email with an inline image to the email address that the user enters. I have been struggling to do it. I checked online and this is what I did.
When I enter an email in development it gives me an error saying,
ActionController::UnknownFormat
This is my ActionMailer Notifier.rb
class Notifier < ActionMailer::Base
default from: "insidespintex#gmail.com"
def enter_email(sending)
#coming = sending
attachments.inline['blank'] = {
:data => File.read("#{Rails.root.to_s + '/app/assets/images/News.png'}"),
:mime_type => "image/png",
:encoding => "base64"
}
mail :to => #coming.email, :subject => 'InsideSpintex is coming soon'
end
end
This is my ApplicationController LandingController.rb
class LandingController < ApplicationController
layout 'landingPage'
def soon
#coming = Coming.new
end
def after
render 'after'
end
def save_email
#coming = Coming.new(soon_params)
respond_to do |format|
if #coming.save
Notifier.enter_email(#coming).deliver
format.html { render action: 'after' }
#render 'after'
else
render 'soon'
end
end
end
#render 'soon'
private
def soon_params
params.require(:coming).permit(:email)
end
end
And this is my View enter_email.html.erb
<p> Hello There,</h3>
<%= image_tag attachments['News.png'] %>
Well, I think that you don't need the encoding part in your attachments.inline hash. I was using something like this on a project:
Mailer method:
attachments.inline['logo.png'] = {
data: File.read(Rails.root.join('app/assets/images/logo.png')),
mime_type: 'image/png'
}
and you are missing the .url in the view:
<%= image_tag attachments['logo.png'].url %>
Related
Basically I want to redirect to a PUT controller action using the redirect_to method but it just wants to use the GET verb. Is there a way to specify the HTTP verb in the redirect_to?
The route is defined as in rake routes
resume_user PUT /users/:id/resume(.:format) users#resume
and I have used all of the following with the same result No route matches [GET] "/users/5/resume"
redirect_to resume_user_url(#user)
redirect_to action: 'resume', controller: 'users', id: #user.id
redirect_to action: 'resume', controller: 'users', method: 'put', id: #user.id
I might be using it wrong, in which case, any suggestions?
Thanks
Patrick
The standard does not allow for this. A redirect with status 307 forbids the browser from changing the request method when following the redirect but there is no mechanism for requesting a particular method be used.
It's an old question, but It not easy to find the answer so...
If you came from an get or post request, you can change the method adding status: 303
redirect_to resume_user_path(#user), status: 303
I had the same scene as the poster and got over it in the following way.
[application_helper.rb]
def parse_from_params(params, anc = nil)
#tags || = []
params.each do |row|
key = if anc
f, b = anc.split
f + "\[#{row.first} \]" + b.to_s
else
row.first.to_s
end
if row.last.is_a?(Hash)
parse_from_params(row.last, key)
else
#tags << hidden_field_tag(key.delete(' '), row.last)
end
end
#tags.reduce(:+)
end
[application_controller.rb]
def redirect_keeped_params(url, **options)
#url = url
#params = options[:params]
#method = options[:method]
render_text = <<-EOS
<%= form_tag #url, method: #method, id: "redirect_form" do %>
<%= parse_from_params(#params) %>
<%= javascript_tag 'document.getElementById("redirect_form").submit()' %>
<% end %>
EOS
render inline: render_text
end
use example...
[posts_controller.rb]
def redirect_to_put_preparation
post = Post.find(params[:id])
params = {}
params[:post] = {title: params[:title], body: params[:body]}
# or params = post_params
redirect_keeped_params(update_post_path(id: post.id), params: params, method: :put)
end
def update_post
post = Post.find(params[:id])
post.update(post_params)
flash[:notice] = "success"
redirect_to root_path
end
def post_params
params.require(:post).permit(:title, :body)
end
Try
redirect_to resume_user_url(#user), method: :put
I've tried using method: :post on link but I haven't tried it with redirect_to.
in my rails 4 app, i have a user model that has_one profile model which also belongs_to the user model
this is my first time using a nested resource so im kinda lost to it
here how it goes
, a user creates an account,after succesful email authentication , user proceed to create a profile. Problem is, im getting error on using the build_association. Im not sure whether the problem is actually that or im getting null values on the params(which i think not)
in my routes.rb
resources :users do
resources :profiles
end
profiles view, new.html.erb
<%= form_for(#profile,url:{ :controller => 'profiles', :action => 'create'},html: {class: "ui large segment form error"}) do |f| %>
<%= render 'shared/form_error_messages', object: f.object%>
<div class="ui horizontal divider">Create a Profile</div>
<%= f.text_field :first_name, :placeholder => "First Name" , :required => true%>
<%= f.submit "Submit Profile", class: "ui submit button"%>
<% end %>
profiles_controller.rb
def new
#user = User.find(params[:user_id])
#profile = #user.build_profile
end
def create
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile has been created"
redirect_to root_url
else
render 'new'
end
end
private
def profile_params
params.require(:profile).permit(:first_name)
end
when im submitting the form, im getting
NoMethodError in ProfilesController#create
undefined method `build_profile' for nil:NilClass
Application Trace | Framework Trace | Full Trace
app/controllers/profiles_controller.rb:9:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"MFCANYra..",
"profile"=>{"first_name"=>"sample",
"commit"=>"Submit Profile",
"user_id"=>"1"}
Try changing the create action in profiles_controller.rb as below :-
def create
#user = User.find(params[:profile][:user_id])
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile has been created"
redirect_to root_url
else
render 'new'
end
end
let me know this worked or not, try to find if something else is causing the problem, thanks.
Hi I have a rails App where Users can have a timetable with a one to many relationship.
When i add this
<%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
to _user.html it renders a delete link which deletes a user no problem
but when i add this
<%= link_to "delete", timetable, method: :delete,
data: { confirm: "You sure?" } %>
to _timetable.html.erb it throws an error
ActionController::RoutingError (No route matches [DELETE] "/timetable.4"):
My Routes.rb
get 'password_resets/new'
get 'password_resets/edit'
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
get 'timetable' => 'timetables#new'
get 'signup' => 'users#new'
get 'mobile' => 'users#mobile'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :timetables
resources :users
resources :projects
Timetable Controller
class TimetablesController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def index
#timetables = current_user.timetables.find(current_user)
end
def new
#user = User.find(current_user)
#timetable = Timetable.new
#timetables = #user.timetables.paginate(page: params[:page], per_page: 1)
end
def feed
Timetable.where("user_id = ?", id)
end
def show
#feed_items3 = current_user.feed.paginate(page: params[:page])
#timetable = current_user.timetables.find(params[:id])
end
def create
#timetable = Timetable.new(timetable_params)
#user = User.find(current_user)
if current_user.timetables.create(timetable_params)
flash[:success] = "Timetable created!"
redirect_to timetable_path
else
flash[:success] = "Timetable not created!"
redirect_to timetable_path
end
end
def destroy
#timetable = Timetable.find(params[:id])
#timetable.destroy
redirect_to timetables_path, notice: "The timetable #{#timetable.name} has been deleted."
end
private
def timetable_params
params.require(:timetable).permit(:name, :attachment, :id)
end
def correct_user
#project = current_user.projects.find_by(id: params[:id])
redirect_to root_url if #project.nil?
end
end
Without seeing your Controllers it is hard to be sure, but I would look at a few areas:
Specifying the path & the timetable object to be deleted:
<%= link_to "Delete Timetable", timetable_path(timetable), :method => :delete %>
Ensure that the destroy action for the timetable sits within the timetable_controller
Regarding your routes.rb file I am not sure why you need:
get 'timetable' => 'timetables#new'
and then also
resources :timetables
This is duplication - why not try use 'only' (edit to your preference):
resources :timetables, only: [:index, :new, :create, :destroy]
I can't figure out what I am doing incorrectly when trying to load ActiveRecord validation errors with AJAX. I cannot get the ajax:error to trigger unless I have already submitted a valid form and triggered ajax:success. I have tried only binding the ajax:error to see if the success could be blocking it. I have read through the rails documentation on working with javascript in rails, and Googled my problem to no avail. I have tried to use both .bind() and .on() but I haven't seen a difference. I am sure there is something incredibly simple that I am missing, but I have been looking at this too long and I don't seem to be getting anywhere.
Here is the code.
Model
class User < ActiveRecord::Base
before_create :set_activation_key
before_save :encrypt_password
before_save :downcase_username
after_save :clear_password
validates :username,
format: {
with: /\A.*\z/,
message: 'invalid'
},
uniqueness: {message: 'already in use'},
presence: {message: 'cannot be blank'}
validates :email_address,
format: {
with: /\A.+#.+\..+\z/,
message: 'invalid'
},
uniqueness: {message: 'already in use'},
presence: {message: 'cannot be blank'}
validates :password, :confirmation => true,
presence: {message: 'cannot be blank'},
length: {:within => 6..20,
:too_long => 'too long',
:too_short => 'too short',
}
def encrypt_password
if password.present?
self.salt = BCrypt::Engine.generate_salt
self.password = BCrypt::Engine.hash_secret(password, salt)
end
end
def clear_password
self.password = nil
end
def set_activation_key
self.activation_key = SecureRandom.urlsafe_base64
end
def downcase_username
self.username = self.username.downcase
end
def self.authenticate(username, password)
user = User.find_by_username(username.to_s.downcase)
if user && user.password == BCrypt::Engine.hash_secret(password, user.salt)
user
else
nil
end
end
end
Controller
class Users::UsersController < ApplicationController
# GET /register
def new
#user = User.new
end
# POST /users
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
UserMailer.registration_email(#user.email_address).deliver
format.html { redirect_to root_path, notice: 'Check your email' }
format.js
else
format.html { render action: 'new' }
format.js { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
def user_params
params.require(:user).permit(:username, :email_address, :password, :password_confirmation)
end
end
Partial
<%= form_for User.new, remote: true do |f| %>
<div id="registration_messages"></div>
<div id="registration_errors"></div>
<%= f.label :username %>
<%= f.text_field :username%>
<%= f.label :email_address %>
<%= f.text_field :email_address %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, 'Confirm Password' %>
<%= f.password_field :password_confirmation %>
<%= f.submit 'Register', :class => 'tiny button' %>
<a class="close-reveal-modal">×</a>
<% end %>
create.js.erb
$(document).ready(function() {
$('#new_user')
.bind("ajax:success", function(event, data, xhr, status){
var $form = $(this);
$form.find('input[type=text], input[type=password], textarea').val('');
$("div#registration_messages").append('<div data-alert class="alert-box success">Check your email</div>');
}).bind("ajax:error", function(event, data, xhr, error){
console.log(event);
console.log(data);
console.log(xhr);
console.log(error);
alert("ajax:error");
});
});
This doesn't help you with your current technique, but you could try doing it in pure JQuery and ditch the js.erb file. I've always found this way more straightforward once you get the hang of it. I would expect something like the following code not to produce the issue you're seeing.
controller
# POST /users
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
UserMailer.registration_email(#user.email_address).deliver
format.html { redirect_to root_path, notice: 'Check your email' }
format.js { render nothing: true, status: :created }
else
format.html { render action: 'new' }
format.js { render json: #user.errors, status: :unprocessable_entity }
end
end
end
javascript.js
# could go in application.js while you're testing it, but best to factor it out into it's own file.
$('form#new_user').on('ajax:success', function(event, data, xhr, status) {
var $form = $(this);
$form.find('input[type=text], input[type=password], textarea').val('');
$("div#registration_messages").append('<div data-alert class="alert-box success">Check your email</div>');
});
$('form#new_user').on('ajax:error', function(event, data, xhr, status) {
console.log(event);
console.log(data);
console.log(xhr);
console.log(error);
alert("ajax:error");
});
I'm creating a newsfeed and have a JSON response set up with Active Model Serializers gem. I'd like to render a regular ERB partial and have it as one of the attributes in the JSON.
controllers/posts_controller.rb:
def index
#posts = Post.all
respond_to do |format|
format.json { render json: #posts.to_a, each_serializer: PostSerializer }
end
end
serializers/post_serializer.rb:
def event_html
ApplicationController.new.render_to_string(:partial => 'events/event', :locals => { :event => object.event }) if object.event
end
Unfortunately, my view has some code that uses helpers and the request object (urls), and I'm getting errors when I try to do this.
events/_event.html.erb:
<div class="event">
<h4 class="title"><%= link_to event.name, event %></h4>
<div class="date"><%= date_range event.start_at, event.end_at %></div>
<div class="description"><%= event.description.html_safe %></div>
</div>
undefined method `host' for nil:NilClass
Any ideas of a good way to solve this problem?
That happens because your controller lacks response attribute.
You may set the request for the controller as follows:
def event_html
ApplicationController.new.tap {|c|
c.request = ActionController::TestRequest.new(host: "localhost")
}.render_to_string(:partial => 'events/event', :locals => { :event => object.event }) if object.event
end
However, for your case I would pass an existing controller as a context to the serializer
controllers/posts_controller.rb:
def index
#posts = Post.all
respond_to do |format|
format.json { render json: #posts.to_a, each_serializer: PostSerializer, context: self }
end
end
# ... or ...
def default_serializer_options
{
context: self
}
end
serializers/post_serializer.rb:
def event_html
context.render_to_string(:partial => 'events/event', :locals => { :event => object.event }) if object.event
end