rails 3 load different partials in mailer action - ruby-on-rails-3

So I have one layout for 2 mail actions: signup_email and change_password
def signup_email(user, url)
#user = user
#url = url
mail(to:user.username, subject:"Welcome to Clubicity!", template_path: "mail_templates", template_name: "system")
end
def change_password(username,url)
#url = url
mail(to:username,subject:"Clubicity - password recovery", template_path: "mail_templates", template_name: "system")
end
I managed to get the one layout for this 2 actions, but now in this layout I need to render 2 different partials depending on what action is called, signup or change_pwd..
I've looked in RailsGuides and api.rubyonrails.org and they say only about templates.
Please, need help with this.

got it using mail layouts like this
def change_password(username,url)
#url = url
mail(to:username,subject:"Clubicity - password recovery") do |format|
format.html { render :layout => 'mail_templates/system'}
end
end
def signup_email(user, url)
#user = user
#url = url
mail(to:user.username, subject:"Welcome to Clubicity!") do |format|
format.html { render :layout => 'mail_templates/system'}
end
end
and in the layout just put <%= yield %>
and rock'n'roll!

So, you want to use one file for different actions. Of course you have to define actions in templates.
I propose to make one view file for each action.
For using one layout just add <%= render 'email_header' %> to the top and <%= render 'email_footer' %> to the bottom of each view. Also make _email_header.html.erb and _email_footer.html.erb with appropriate markup.

Related

No route matches {:action=>"show", :controller=>"restaurants"}

If I want to go with my home page clicking on the map localhost:3000/maps gets out this error No route matches {:action=>"show", :controller=>"restaurants"}
controllers/maps_controller.rb
def index
#maps = Map.all
#json = Map.all.to_gmaps4rails do |map, marker|
marker.infowindow info_for_restaurant(map.restaurant)
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
def show
#map = Map.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #map }
end
end
private
def info_for_restaurant(restaurant)
link_to restaurant_path do
content_tag("h2") do
restaurant.name
end
end
end
routes.rb
resources :restaurants
resources :maps
This is answer for my question:
controllers/maps_controller.rb
def index
#maps = Map.all
#json = Map.all.to_gmaps4rails do |map, marker|
marker.infowindow render_to_string(:partial => "/maps/maps_link",
:layout => false, :locals => { :map => map})
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maps }
end
end
views/maps/_maps_link.html.erb
<div class="map-link">
<h2><%= link_to map.restaurant.title, map.restaurant %></h2>
</div>
You referred to restaurant_path within info_for_restaurant, which is part of MapsController. Rails met error here.
You need to either define the restaurant_path in restaurant controller, or comment out this function in maps controller at this moment.
Your approach is wrong in several levels. Let's work on them, one at a time:
1) Your call to the route helper is wrong:
restaurant_path is the route helper for a show action. A show action needs an id parameter to be valid. Your call is missing a parameter.
So, your code must be something like this:
def info_for_restaurant(restaurant)
link_to restaurant_path(restaurant) do
content_tag("h2") do
restaurant.name
end
end
end
To see the parameters needed for each action, you can run rake routes on the console.
However, this does not solve the problem, as you're also:
2) Calling view helpers from your controller
link_to and content_tag are view helper methods, and you don't want to bother your controller with view issues. So, the best way to solve this problem is to move your info_for_restaurant method to a helper, and call it from a view instead.
So, now, your controller will not assign anything to #json, and the last line of your view will look like this:
<%= gmaps4rails #maps.to_gmaps4rails {|map, marker| marker.infowindow info_for_restaurant(map.restaurant) } %>

Submitting form via multiple partials

I have a really long form which I would like to break up into about 5 partials. When the user hits 'Next' at the bottom of each partial I want to use AJAX to load the next partial until the last partial submits the entire form into the database. Also, if the user hits 'Previous' I need the fields to be populated with what the user filled in previously.
So far I have this which is not working:
users/new.html.erb
<%= form_for(#user, :html => { :class => "form-horizontal" }, remote: true) do |f| %>
...
<%= f.submit "Next" %>
users_controller.rb
def create
#user = User.new(params[:user])
if #user.save
respond_to do |format|
format.html { flash[:success] = "Welcome to Friends First!"
redirect_to #user }
format.js
end
else
render :new
end
end
create.js.erb
$("#site_content").html("<%= escape_javascript(render('layouts/partial2')) %>");
I would put each of the 5 parts into separate divs (display: none) and only show (display: block) the first. When the user clicks "next", I would show the second, etc. The final submit to the create action can also be done via jquery through
$.ajax(
url: '/users',
type: 'post',
data: $("form").serialize()
)
I hope, that helps.

How to create a custom POST Action in Rails3

I am trying to create a custom POST action for my article object.
In my routes.rb, I have set the action in the following way:
resources :articles do
member do
post 'update_assigned_video'
end
end
In my articles_controller.rb I have:
def update_assigned_video
#article = Articles.find(params[:id])
#video = Video.find(:id => params[:chosenVideo])
respond_to do |format|
if !#video.nil?
#article.video = #video
format.html { redirect_to(#article, :notice => t('article.updated')) }
else
format.html { render :action => "assign_video" }
end
end
Then in my view I make a form like this:
<%= form_for #article, :url => update_assigned_video_article_path(#article) do |f|%>
[...]
<%= f.submit t('general.save') %>
The view renders (so I think he knows the route). But clicking on the submit button brings the following error message:
No route matches "/articles/28/update_assigned_video"
rake routes knows it also:
update_assigned_video_article POST /articles/:id/update_assigned_video(.:format) {:action=>"update_assigned_video", :controller=>"articles"}
What am I doing wrong?
Is this the wrong approach to do this?
Your form_for will do a PUT request rather than a POST request, because it's acting on an existing object. I would recommend changing the line in your routes file from this:
post 'update_assigned_video'
To this:
put 'update_assigned_video'

How do you pass validation errors across controllers?

I'm making a conventional forum in Rails to practice. I have a Topic model and a nested Post model. Topics can have many Posts.
Topics#Show has a list of #topic.posts and then a new Post form.
# Topics#Show
def show
#topic = Topic.find(params[:id])
#post = #topic.posts.new
end
Submitting a new post sends it to Posts#Create
# Posts#Create
def create
#topic = Topic.find(params[:topic_id])
#post = #topic.posts.new(params[:post])
#post.user = current_user
if #post.save
redirect_to #topic, :notice => "Successfully created post."
else
render :action => 'new' # <-- Unsure what to do here
end
end
If the Post fails to save, I want it to render Topics#Show and display the validation errors there.
From what I understand, params don't persist through a redirect_to because a 302 redirect starts a new request.
You should render the topics/show view. So instead of
render :action => 'new' # <-- Unsure what to do here
Do:
render :template => 'topics/show'
Use render :template => "topics/show" and be sure to set up the #topic variable identically to how you do it in the TopicsController#show action. You will not be able to call this show method from the PostsController though.

How does Rails 3 actionmailer decide which format to use?

In documentation it says, that mailer actions behave in very similar fashion as controller actions.
In rails guide, to send mail:
UserMailer.welcome_email(#user).deliver
and welcome_email action looks like this:
def welcome_email(user)
#user = user
#url = "http://example.com/login"
mail(:to => user.email, :subject => "Welcome to My Awesome Site") do |format|
format.html { render 'another_template' }
format.text { render 'another_template' }
end
end
what I don't get is, how welcome_email action decides which format to use (html or text)?
Thanks!
I believe it will create a multipart email that includes both html and text parts. This will allow text only clients to render it using that part and html based clients to render it properly too.
Rails 3: http://guides.rubyonrails.org/action_mailer_basics.html
Rails 2: http://guides.rubyonrails.org/v2.3.8/action_mailer_basics.html