How to prevent Rails from rendering links when using partials in Mailer - ruby-on-rails

I would like to reuse my partials in mailer layouts, but I want to avoid rendering the hyperlinks and instead print out just their name, like using link_to_if / link_to_unless methods.
Which condition could I check to prevent the rendering all the links inside mailer layouts?

Inside your email view, you can use something like this :
<%= controller.class.name %>
The printed controller name will be a mailer : "ApplicationMailer", ...
You can then Regex or use a string helper ...

Related

Rails - return html black from model

I have a method in my model which is called in a modal like this:
<div class="col-sm-9"><%= #notification.notifier_context %></div>
In this method, I want to return some HTML like this, which has a rails helper path in it.
context = "<td><%= link_to('link', account_item_path(#item.account, #item))%></td>".html_safe
But its just out-putting the string as is. How can I get it evaluated to HTML proper?
Thanks
Try:
"<td>#{link_to('link', Rails.application.routes.url_helpers.account_item_path(#item.account, #item))}</td>".html_safe
String is not erb template so you can't use <%= %> syntax.
Also it's great idea to use helpers (with content_tag) or partials for that.
Also if you need to use routes inside model class, read following answer.

Using helper methods in views

I'm having some trouble realising how the helper methods should be used in views. For example, take these parts of code:
Mycontrollers_helper.rb
module MycontrollersHelper
def destroy_everything
Model.destroy_all
redirect_to root_path
end
end
How should it be used in the view then ? Let's say adding the method to a button in the view:
<%= button_to 'Destroy all', destroy_everything, method => :post %>
Is just writing a method in the helper.rb file enough or does it require some additional lines in the controller it refers to ? Is this even the correct syntax for something like this ?
Helpers in rails actually view helpers. So they are meant to provide some help to render your views.
If you want to delete something, and then redirect to some action, just use a controller action for that.
I think you are taking about view helper, which you want to call from your view template.
You can call your view helper with the name of the method.
Calling destroy_everything will works fine if this helper is included in your controller.
Update:
If you write your helper method in application helper then you don't need to worry about load/ include the helper.

Render output of HTML stored in database in Rails

I have some html content stored in a database field. I would like trusted admins in our system to be able to edit the HTML when needed. Eventually this html will be converted into an email message and sent to users. In addition to the static html content, the email message has a first and last name that is stored in an active record model.
I was hoping to leave the <%= user.firstname user.lastname %> inside the HTML text when the admins are editing the content and then eventally combine the content with embedded erb the email renderer. I have the part where the admins can save the HTML working fine.
However, even ignoring the email and just trying to render to a normal web page, I am not able to get a view to correctly substitute the embedded <%= ... %> with the information from the database. I always see the <%= ... %> instead of the substituted text. I have tried render_to_string, render :inline, etc.
In summary, I am trying to:
Take some html text with embedded some erb from the database
Run the text through a template where the embedded erb is replaced with the variables passed into locals
Take the resulting text block and either email it to users or display on a web page depending on my needs
The problem is that the results always have the <%= ... %> in it instead of the substitutions.
In an example controller I have:
def showit
#storedhtml = mymodel.savedhtml
#emailtext = render_to_string( template: 'e.html.erb',
layout: false, locals: { user:#user })
end
The e.html.erb contains:
<%= raw #storedhtml %>
and the showit.html.erb has:
= raw #emailtext
I have also tried using inline like this:
def showit
# the line below is substituted but the <p> tags are not converted
#stuff = "<%= '<p>testme</p>' + user.firstname %>"
#storedhtml = mymodel.the_html_content
#output = render( inline: #storedhtml, locals: { user:#user }, layout: true )
end
In a controller you wouldn't use Erb syntax, you'd use normal Ruby string interpolation:
#stuff = "#{'<p>testme</p>'} #{user.firstname}"
# Or, since the HTML isn't dynamic:
#stuff = "<p>testme</p> #{user.firstname}"
And to output it in the view you'd need to use html_safe:
<%= #stuff.html_safe %>
In general, generating HTML directly in the controller isn't a great idea since there are other mechanisms in place, and it creates another place to look when you're trying to figure out what component creates which HTML.
Edit I misunderstood. Another templating engine like Sameera suggested is one option, or just evaluate the DB value as an erb template using your current binding.
You could also create a template resolution component that would allow retrieval directly from the DB if no file is found; the Crafting Rails Applications book discusses this.
I guess what you need is 'liquid' - it's a template language for Rails.
Check this out:
http://liquidmarkup.org/
http://railscasts.com/episodes/118-liquid
Assuming you have a Model with attribute named "template" which returns some html template (with ERB), if you want to render it you can use something like this into your controller's action:
render inline:"<%= raw ERB.new(#your_var.template).result(binding) %>".html_safe, layout:'application'

How to vary a helper called within a Rails 3 layout, depending on the controller

I'm using the same layout for several controllers, and inside this layout I include a menu using a call to a helper, like this:
<%= side_menu %>
What I'd like to do is vary the contents of side_menu depending on the controller that's invoking the layout. In an ideal world, I could define side_menu in application_controller.rb and in other helper files and then the appropriate helper would be selected depending on the controller; in other words, something like this:
# application_helper.rb
def side_menu
"generic menu This goes here"
end
# users_helper.rb
def side_menu
"menu for users goes here"
end
# guests_helper.rb
def side_menu
"menu for guests goes here"
end
This doesn't work because in Rails 3 all helper files are loaded and I have no control over which side_menu will actually be called. It would be great if there were an option to load only application_helper.rb and the controller-specific helper, but there's not one (yet).
What's the best way to vary the content of a helper depending on the controller? I'm currently defining side_menu once in application_helper.rb and then checking to controller to see what to add. This feels wrong, since the problem nearly screams for a subclass-and-override answer -- which I can't do due to the "helper :all" behavior of Rails 3. Suggestions?
You can define this method in controller and add:
helper_method :side_menu
But maybe different solution would be better. I think that you can add _side_menu.html.erb in each controllers view folder and when you call <%= render :partial => 'side_menu' %> it should look for different files depending on current controller (however rememeber to add this file for all controllers).
Or you can mix these two methods. Add this helper method to controller and inside it render right file. This way it is better, because you get some default side menu and it won't crash when there is no side menu partial for a controller.
You can also in layout add <%= yield :side_menu %> and if you want to put something in side menu, just add <% content_for :side_menu do %> bla bla bla <% end %>.

How can I create a "partial" that has its own action?

In my rails application, I render a partial on multiple pages, and in that partial is a variable. So currently, lets say I have 5 pages that render :partial => "partialname", and inside of partialname is #variable.
Can I have it so that partialname has its own action with #variable instantiated inside, rather than having #variable be called 5 times from each action that renders the partial?
Thanks!
I would create a before_filter on all the methods that need the common behavior.
But if you really want the partial to have its own "action," make a helper method that does whatever "action-y" things you want and then renders the partial. That works out to essentially the same thing. I've done this before to make a template-type partial that contains various pieces of data that need processing.
Rails Sub-controllers?
See my answer on this.
Very similar method here, using before filters either using controller inheritance or modules when needed.
So, is this a problem of code running 5 times per request that you'd rather not? Like, you've got a partial and in it is:
#my_var = MyModel.some_expensive_method
If so, you could just cache the result in the model:
def cached_some_expensive_method
#some_expensive_method ||= some_expensive_method()
end
you could load #variable from the view:
&lt% #variable = Variable.find(:whatever) %>
but some consider this bad practice in not adhering to strict MVC. This does have the benefit of supporting fragment caching out of the box:
&lt% cache({:variable_id => :whatever}) do %>
&lt% #variable = Variable.find(:whatever) %>
. . .
&lt% end %>
Is there a common model that's being rendered in the main views that you could delegate the variable access to?
&lt%=h #model.variable %>

Resources