I have here a problem with partials in a view of an ActionMailer. They just do not work - and I do not know, if I do something wrong, this is a bug or this is not supported at all.
This should be working as this would be needed to have also DRY code in the mailer views (. From my testings, I see, that helpers are working (after including them into the ActionMailer class)
I am using: Rails 4.0.0 on Ruby 2.0.0-p247
Error Message:
ActionView::MissingTemplate at /events/81/user_invitations
==========================================================
> Missing partial user_invitation_mailer/test_partial with {:locale=>[:en], :formats=>[:text], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}. Searched in:
* "/Users/user/Sites/participate/app/views"
* "/Users/user/.rvm/gems/ruby-2.0.0-p247/gems/devise-3.4.0/app/views"
But this partial is there! - I am not allowed to upload pictures... structure is:
- views
-- user_invitation_mailer
--- _test_partial.html.erb
--- user_invitation.text.erb
Details:
call in the Controller:
UserInvitationMailer.user_invitation(#invitation).deliver
UserInvitationMailer:
class UserInvitationMailer < ActionMailer::Base
add_template_helper(MailerHelper) # for testing including helpers.
def user_invitation(invitation)
#invitation = invitation
mail(to: #invitation.email, subject: 'Invitation')
end
end
user_invitation.text.erb:
Hi <%= #invitation.email %>,
This is a test email see:
<%# test_helper %>
<%= render partial: 'test_partial' %>
Thanks
_test_partial.html.erb:
"Test the partial."
(adding:)
Not working:
<%= render partial: 'test_partial' %>
<%= render partial: './test_partial' %>
<%= render partial: '../test_partial' %>
<%= render partial: 'user_invitation_mailer/test_partial' %>
The rails console give you nice explanation where it is looking for partials:
Missing partial user_invitation_mailer/test_partial with {:locale=>[:en], :formats=>[:text], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}.
Searched in:
"/Users/user/Sites/participate/app/views"
So the root folder for partials is your views folder.
You can create new folder:
/views/partials/_some_partial.html.erb
and in your template:
render "partials/some_partials", local_variables: #model.some_variables
or just render full path partial:
render "/user_invitation_mailer/test_partial"
UPD
For complete answer please see comments below
in rails 4 you can try with <%= render 'test_partial' %> it will work.
Were you able to find a solution? I am having the same issue. But able to render a partial if defined some shared folder.
Edit - Found the issue. I was not properly closing the call.
Related
I have two template folder in my web/templates folder:
> ls web/templates
personal_info user
What I want is to render some template from user folder in another view of personal_info. so I have a file at path: web/templates/personal_info/index.html.eex, I have following content:
<%= render "user/xyz.html" %>
But I get following error:
[error] #PID<0.821.0> running MyApp.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /
** (exit) an exception was raised:
** (Phoenix.Template.UndefinedError) Could not render "user/xyz.html" for MyApp.PersonalInfoView, please define a matching clause for render/1 or define a template at "web/templates/personal_info". The following templates were compiled:
* index.html
Please tell me how do I render template defined in other folder, I tried few permutations, but none worked.
Phoenix templates are just functions, so when you want to render your UserView's "xyz.html" template from your PersonalInfo's view, you just call the function!
Let's say you are inside the web/templates/personal_info/show.html.eex template. (Phoenix.View.render is already imported for you):
<%= render UserView, "xyz.html", user: user %>
Of if you want to pass along all the template assigns that your PersonalInfo template was provided:
<%= render UserView, "xyz.html", assigns %>
As you found, this works from anywhere, because templates are Just Functions. For example, the same thing would work in iex:
iex> Phoenix.View.render(MyApp.UserView, "xyz.html")
"<h1>User ..."
As of Phoenix 1.5.1
Phoenix matches controllers, views, and templates by names. It can be changed by put_view like:
conn
|> put_view(MyAppWeb.SpecialView)
|> render(:show, message: "Hello")
https://hexdocs.pm/phoenix/Phoenix.Controller.html#render/3-views
For me worked when I specified application name:
web/templates/product_gallery/index.html.eex:
<p>Please, render me!</p>
web/templates/kitchen/index.html.eex:
<%= render APP.ProductGalleryView, "index.html", assigns %>
If I am trying to render without application name I am getting:
undefined function ProductGalleryView.render/2 (module ProductGalleryView is not available)
I'm on Phoenix 1.3.0. Seems like I had to add
alias MyApp.Userview
to web/views/personal_info_view.ex, then
<%= render conn, UserView, "xyz.html" %>
Without the alias above, then you have to
<%= render conn, MyApp.UserView, "xyz.html" %>
Apparently following worked:
<%= Phoenix.View.render(MyApp.UserView, "xyz.html") %>
please let me know, If there are better alternatives.
Source: this.
I'm having a routing issue with an image. In my app I have images of items on the home page. I would like them to link to their image page.
Here is what my items controller looks like:
class ItemsController < ApplicationController
def show
#item = Item.find(params[:id])
end
end
This is what I have in my routes:
Rails.application.routes.draw do
resources :items
end
And this is what I have in the item partial:
<%= link_to(image_tag(item.image.url(:thumb)), item_path(:id)) %>
What I expected after reading the rails routing guide was that this would link to the item page for that image. Here is their example:
photo_path(:id) returns /photos/:id (for instance, photo_path(10) returns /photos/10)
I should also add that this is in my home page controller:
class StaticPagesController < ApplicationController
def home
#items = Item.where.not(category_id: 1)
end
However, that is not working. I've tried several different things, but all produce errors. Is there a simple way to do this?
The normal way to do what you want is this:
<%= link_to item_path(item) do %>
<%= image_tag(item.image.url(:thumb)) %>
<% end %>
You can just pass the instance of the item to item_path and also if you have complicated html for a link, it is usual to put it in a block for the link as shown here (with link_to something do).
I am a beginner to Rails. Was working along with Railsguide for Rails 4.
One confusion i have is:
for adding a link , somewhere it is written like:
<h1>Hello, Rails!</h1>
<%= link_to "My Blog", controller: "posts" %>
whereas somewhere its like
<%= link_to 'New post', new_post_path %>
Please clarify the difference.
Good question. Both of these are link helpers, and both are resource-oriented (check out the Rails UrlHelper docs for more information).
The first one will render a link that is associated with the particular controller:
<%= link_to "My Blog", controller: "posts" %>
<a href='/posts'>
The second will render the Rails path specific to creating a new Post object (this is also resource-oriented). Check out section 2.3 in the Rails routing guide:
<%= link_to 'New post', new_post_path %>
<a href='/posts/new'>
Hi I want to preface this by saying that I am new to coding.
I have an issue that I believe can be solved in two ways
A. by rendering a partial
B. by updating the controller
( I can totally be wrong but these are what I suspect lol)
I have two controllers/views "reviews" and "logs". and I want them to both appear on the same page.
How can I do this?
I tried rendering a partial but I alway get an error.
and I tried the piece of code below:
which made my reviews show up on the page, but when I add
#log = #user.logs.all
to it, it doesn't pull all the logs to the page like it does for the reviews.
def show
#user = User.find_by_name(params[:id])
if #user
#reviews = #user.reviews.all
render action: :show
else
render file: 'public/404', status: 404, formats: [html]
end
end
First things first. Views refer to actions in controllers. So there can be several views for each controller or even none.
So, if you want to render #reviews and #logs on the same page you should first instantiate both instance variables in the same action and then render both partials in the same action.
How do you do that? Easy.
First you got to the controller you just showed and edit that show action.
def show
# You can set the variable in the if-clause
# And you also need to use static finders with a hash as an argument in Rails4
if (#user = User.find_by(name: params[:id]))
#reviews = #user.reviews.all
#logs = #user.logs.all
# You don't need to call render explicitly
# if you render the view with the same name as the action
else
render file: 'public/404', status: 404, formats: [html]
end
end
Second: you go to your /app/views/reviews/show.html.erb template and put both partials there like this (this is just an example, adjust your markup to fit your needs).
<h1> Reviews and Logs</h1>
<div id="reviews_part">
<%= render #reviews %>
</div>
<div id="logs_part">
<%= render #logs %>
</div>
Now create 2 new partials /app/views/reviews/_review.html.erb and /app/views/logs/_log.html.erb and put all the needed markup there (use regular variables review and log to adress the repeating objects). Rails will automaticaly repeat those partials as many times as needed.
Or you can explicitely call the partial render
<div id="reviews_part">
<% #reviews.each do |review| %>
<%= render review %>
which is the same as
<%= render partial:"reviews/review", locals:{review:review} %>
<% end %>
</div>
Here is the way of rendering partials into views in HAML:
=render :partial => "header"
%h2 Hello World
=render :partial => "footer"
Every partial you render this way, has to be created within the same folder.
Each partial's name has to begin with an underscore (_). This should be the view's directory:
- home
- index.html.haml
- _header.html.haml
- _footer.html.haml
I've been having this annoying problem in which I click over a select dropdown input of my custom form, styled with Zurb Foundation 4 in my Rails application, and the list won't show its elements.
I thought at a start that was a problem with simple form, but I changed the f.association for f.collection_select, my code looks like this:
<h2><%= I18n.t(".sign_up") %></h2>
<%= simple_form_for(resource, :html => {:class => "custom"}, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
<%= devise_error_messages! %>
<%= f.input :rut %>
<%= f.input :name %>
<%= f.input :email %>
<div>
<%= f.label :supplier_type_id %>
<%= f.collection_select :supplier_type_id, SupplierType.all, :id, :name %>
</div>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= f.error :base %>
<%= f.submit I18n.t(".sign_up"), :class => "button" %>
<% end %>
<%= render "devise/shared/links" %>
The most strange thing is that sometimes I'm able to see the items when refreshing the page, but when I get to the page navigating from other view of the app then it won't work. I've also noticed this when using hints for forms (i.e: If I have two hints in the same form, in different inputs, only one would show, but the same one message displays in both inputs when each message should show in their respective input. When reloading the page sometimes it shows one hint, and sometimes the other)
The styling looks good, so I think that it might be a foundation javascript problem.
Another thing I've noticed is that when I load the page the styling does a kind of "blinking" when using custom forms. This blinking it looks likes foundation takes a while to load the styling, I've also noticed this on their own custom form documentation site. This may indicate that is a form styled with javascript events or something similar, so this might mean that javascript is working well.
In addition, the checkboxes are having a similar problem, they only can be checked just when you reload the page, it might have some relation with this problem.
I'm very lost, some help would become very handy. Thanks!
--edit: Foundation 5 doesn't include custom forms and works better--
You might need to refresh dropdowns on each page:change event. Try something like this:
$(document).on("page:change", function() {
// SELECTOR_TO_CUSTOM_DROPDOWNS should select any Zurb custom dropdowns you
// are using.
$(SELECTOR_TO_CUSTOM_DROPDOWNS).trigger("change");
});
That's from the documentation on Zurb custom form JS.
Yes, this is caused by turbolinks. It stops $(document).ready from firing on page load, which is required by foundation's custom forms.
Using ssorallen's answer and to be more unobtrusive than the OPs, add this to application.js:
$(function(){ $(document).foundation(); });
$(document).on("page:change", function() {
if ($('form.custom').length > 0) {
$(document).foundation('forms');
}
});
Also, if you have jquery/coffeescript that relies on document ready being fired, add jquery turbolinks to your Gemfile.
Ok, so I just figured out that I have repeated asset load on my browser. This is causing a javascript error. It appears that deleting in the manifest
//= require turbolinks
Solves the problem.
I solved my multiple asset problem changing
<%= javascript_include_tag "application" %>
To the head in my application layout.
After watching the turbolinks railscast I noticed that besides my multiple asset loading, turbolinks and foundation 4 may not be compatible, it might be a solution on this post. But still doesn't work perfect for me.
I also noticed that navbar is also affected by turbolinks.
I think that this is rather a turbolinks problem and not an specific foundation dropdown. I will close this question and open a new on turbolinks and foundation.
Thanks to some Nick Reed insights I found out that the foundation gem was initializing foundation in application.js like this:
$(function(){ $(document).foundation(); });
So I checked the docs and I used this:
<script>
$(document).foundation();
</script>
After the "/body" tag in the application layout and everything seems to be working like a charm!