Benefit of some rails commands over direct HTML - html

Can someone explain why I woud use rails link_to etc instead of straight HTML code? Given that they will render the same once they get to the browser - what is the actual benefit here?
<img id="logo" src="images/logo.png" alt="logo" />
<%= link_to image_tag("logo.png", :alt => "logo", :id => "logo"), root_path %>
Background - I was changing this in a template and stopped to think why am I doing this?

In Rails 3.1, using the helper method would make use of the asset pipeline. For the URLs, that means that the images are postfixed with a checksum (this is called fingerprinting, at least in the Rails guide linked above). That allows to set the HTTP server cache expiration to a maximum - if the file content changes, it will result in another filename and thus force redownloading the file. Otherwise it'll be served from the browser cache.
Also, if you specify an asset host in your configuration, the helper methods will use this information - check out the documentation for image_url.
As for link_to, well, I suppose you could also do something like Link, but using the ruby code is more elegant in my opinion.
You should never hardcode the URL in HTML - it might change, and you really don't want to go through your source code and change all references to index.html to home.html or anything like that.

This is a great question. I consider it better practice to use the rails link_to method as well as the other html helper methods. In this case, it may not have an clear advantage, but more times than not it does. Here are some cases where it is helpful:
Changing Routes
If you have a named route, say foo_path which directs to /foo. You can use <a href='/foo'>, but if you wanted to change foo_path to route to /foo_bar - you would have to go through each view and manually change the links.
Variables
It is common to need a variable for a link. It is more elegant to have <%= link_to #foo.name, foo_path %> than <a href='/foo'><%= #foo.name %></a>
Look and maintainability
In my experience, view code that utilizes helper methods tends to look better and is easier to refactor and maintain.

The helpers expose functionally you don't necessarily always use, like ":remote => true", or automatically including an app context, or bringing in the asset pipeline.
For the simplest use cases there is often little or no benefit, but that's not where helpers shine-they're for when things go cows-legs-up and the "raw" form includes logic too bulky to remain in the mainline template.
Using them for the simple use-cases keeps things consistent, and makes templates more resilient to change.

Related

Move 2sxc <script> to external file when it has razor content

I'm trying to make my CSP without unsafe inline.
Since I have to manually check every file from every app, I may as well move the scripts to external files instead of creating a million word CSP entry in the web.config by adding hashes or nounces.
This seems easy enough for client side content, but many templates have razor code in then such as:
<script>
alert(#myVar);
</script>
How can I move this to external?
So in general if you JS needs some input parameters you must of course put them somewhere, and only the razor will know what they are.
The simplest way is still to just have the initial call use the variables - like in your example above. If you have security concerns, doing type-checking in razor should eliminate that for you.
For example, if you do #((int)thing.property) than it simply cannot inject any unexpected payload.
If for some reason you really, really don't want this you can use a attribute-json convention, like
<div class="myGallery" init='{"files": 17}'> gallery contents </div>
and pick it up from the js you created. but this is quite a bit of work, so I would recommend the simpler way.

Rendering page with HUGE amount of HTML

I'm creating a website that has a huge amount of HTML (many thousands of div elements). There's no real way to get away from having all these div elements and it's making the site load very slow (7-12 seconds). I've tried putting caching on the site, but it doesn't help, since the site still has to render all these div elements.
More specifically it's 140 dropdowns, that each contain 100-800 div elements and they take a long time to show.
My thoughts, was to render the div elements that are inside the dropdowns, after the page loads, but I don't know how to go about that?
What is the easiest way to render some of your partials AFTER the page has loaded? I'm using Rails 4 btw.
Any other suggestions on how to deal with HUGE amounts of HTML?
I have a similar issue on one of my pages. Here are some things to try related to the select boxes.
(The top two may not be relevant since you said you tried caching, but I'm including for completeness. What type of caching did you try? How did you verify it was the browser rendering that was slow?)
Double check the cause of the problem
Comment out the code that generates the select boxes and check whether the time in your rails logs (as opposed to your browser measurements) drops. This establishes your "lower bound" for performance improvements on that measure.
Avoid using rails helpers.
If you're using select_tag, options_for_select, or any of that family of methods you may be doing a lot of repeated work since each time they are called they need to rebuild the list of options. If the options are the same for each select box, you can build them up once then just dump them in the page:
<% options = options_from_collection_for_select(#array, "id", "name") %>
<%= select_tag "myfield", options %>
If you need different selected values for each, you can try:
Processing options after creation to add them. This is pretty gross and possibly won't give you much speed up over the default generators.
Dump the defaults into a javascript variable, then set them with JS after the page loads.
AJAX in partials
This will give the illusion of loading faster, even though server time is the same (though it may be parallelized somewhat, you add extra network delay). The easiest way to do this is with jQuery's .load method.
$("#element-1").load("/path/to/partial/1")
Generate select boxes in JS
If you can get all the data you need to the client relatively fast (maybe serve it up in a JSON endpoint?) you can try building up the select boxes directly with jQuery, which is covered in Programmatically create select list
Remove redundant HTML
Why do your dropdowns have divs inside them? Is there a way to simplify?
Although the question is few years old, maybe someone will benefit from this one.
1) in controller:
#companies = Company.all.pluck(:name, :id) #order is important here
2) in view:
<%= f.select(:company_id, options_for_select(
#companies, selected: #user.company_id
), {}, class:"form-control m-b") %>
pluck grabs only :name, :id values, array of arrays, e.g,
=> [["Sumptus xiphias canto.", 5], ["My First Co.", 1]]
is created and then options_for_select populates options.
My 5000 records are populated in ~300ms in AJAX modal window. Not super fast, however I don't think regular user would complain.

Upload Image not using erb (form) rails

I was wondering if there is a way to upload images in rails 4 not using erb. I have my html code in quotations in my model (so that i can use it as a default for when creating a page). SO I cant put erb in the quotes, cuz if i do it'll come out as the erb code and not the actual view. (i.e. the upload image form. itll come out as the actual f.image_tag instead of the actual upload button).
So I am just seeing if there another way i could implement image uploading into the quotations that wont require erb. But, uses Rails 4.
If you have plain HTML code inside the string, and just want it to be displayed, you need to call .html_safe in your view, like:
'<div id="foo">bar</div>'.html_safe()
Note that normally is a bad practice: that doesn't mean it is always bad, but it means that it is always an attention point to make sure it is the best way to do it.
If you want to do image upload without using form.image_tag, you can just put that in your view and see the generated code (Ctrl+U in Chrome), that, in this case, will be something like:
<input type="file" id="something" />
And add that to the string. Probably some finer validation and options are added too via JS, that would be a pain to add this way - one way to be to add a script tag to the html with the code.
If, however, your string already contains code like this, and you are asking way it is not working, then you need to add an eval to the caller, e.g.:
eval('form.image_tag :image')
Not that this is an even worse smell, and it should be avoided at all costs.
Maybe it would be better to add some flags in your section.rb model, and then use that in a helper or in the view render the html; for example, a has_upload? field, and then you can do something like this:
if #section.has_upload?
form.image_tag :imagem
end

ASP.NET MVC: ActionLink vs bare url

In ASP.NET MVC I see I have handy HTML helpers that I can use to construct form fields and any number of other little things. But then there's 'ActionLinks'.
Why use an ActionLink instead of just writing the darn url myself in an HTML anchor tag?
In other words, why would I use
<%: Html.ActionLink("Back to List", "QuantityTypes") %>
instead of just using plain ol' HTML and writing:
Back to List
Surely, I must get something extra with the ActionLink. I'm just missing it, right?
The action link will build you the proper URL based on the controller, action, areas, params, etc... It generates the URL based on the URL mapping rules defined in the your MVC routing system. It will map params to the correct url as well depending on if it needs to be included in the URL directly or via a querystring param.
Yes you could do it on your own and just type it all out but it builds the URL for you and ensures the URL that is generate is correct. It's a helper function... it helps you produce valid links :)
You should read Scott Guthrie's post and pay extra attention to the section "Constructing Outgoing URLs from the Routing System". It gives the why and explains other helpers that leverage the routing system.
You get centralized control of your URL's. So next time you need to change one for SEO purposes, you don't have to go searching for every place in the application, just switch it in the Global.asax.
What if you wanted to change the controller name from Internal to External. What is going to happen? You are going to need to change the href link by hand. ActionLink will do automatic routing. You don't need to mess with urls.
Another reason for using ActionLink over bare url is that you may need to expose a download link to a secured resource that can only be accessed by the application through identity impersonation.

Are ASP.NET MVC HTML Helpers overrated?

It is quite possible that I may not have got the point, but I really can't figure out how ASP.NET MVC's HTML Helpers can help me. Here's a sample: -
HTML:
Click Me
HTML Helper:
<%= Html.ActionLink("Click me", "ActionName", null, new {target="blank"}) %>
My eyes are reading HTML more easily, and it seems counter-intuitive to use the HTML Helpers.
Look at the following arguments:
A lot of people (even novices) know how to read HTML. The HTML Helper syntax can confuse easily.
In many cases you need to do more typing writing an HTML 'helper', then you need to write the actual HTML.
The HTML Helper is going to spew real HTML anyway, so why not write HTML directly?
Writing HTML gives you more control over the syntax, and the standards. You can make it conform to whatever HTML standard you want.
Are there any special compelling reasons that I have not understood (since I am self-educated in MVC and there could be gaps) that should make me want to prefer HTML Helpers?
Or are they just code noise?
The primary reason you don't use <a> tags directly is that you don't want to hardcode URLs in your application. The Html.ActionLink method will abstract away the URL generation and you'll specify the controller, action, and other parameters.
So, basically, the two lines you posted in your question are not really equivalent. You should consider adding the dynamic URL generation code to the <a> tag to make them functionally equivalent. Beside that, if you output HTML directly, you'll have to be extremely careful about HTML encoding stuff. Html.ActionLink will do this job for you too.
Let's say that you have many query parameters in the URL like
site.com?a=1&b=2&c=3&d=4&e=1&f=1
<%= Html.ActionLink("Click me", "ActionName", null, new {a=1, b=2, c=3, d=4, e=1, f=1}) %>
The actionlink can build this URL for you. If you didn't have the helper you would have to manually add keys and vlaues to the URL. And this is a real pain. The URL helper can also match URL routes too.
Even better, use MvcContrib and ditch the error prone "magic strings" and replace them with lambdas.
<%= Html.ActionLink<MyController>(x => x.ActionName() ,"Click me",new {target="blank"}) %>
Actually, there's no big difference between
Click Me
and
<%= Html.ActionLink("Click me", "ActionName", null, new {target="blank"}) %>
because in both cases you're hardcoding (URL in the first, action name in the latter).
That's why I create specific helper methods for links, and then I use
<%= Html.LinkSomeAction("Click me") %>
This way I'm sure that when I'll change my mind on which name the action should have, I'll be fine; also, I'll never have to worry about misstyping action names or links.
The solution proposed by mxmissile is also good.