Display #obj#{count} properly in rails - ruby-on-rails

How would i get <%= "#obj#{count}" %> to actually display the variable value in the DOM instead of #obj0, #obj1, etc
I've got variable #obj0, #obj1, #obj2, etc that I need to display

A couple of ways.
First, the most correct (IMHO) is to put all your vars to an array and index that.
arr = [#obj0, #obj1, #obj2]
<%= arr[count] %>
Another option is to use eval. Avoid this (unless you really know what you're doing).
<%= eval("obj#{count}") %>

I am not quite sure what you are going for but I think you want
<%= #obj.count %>

Related

Variable + HTML to Button + Ruby on Rails views

I am having a an issue.
<%= link_to "<button>Add</button>".html_safe, new_admin_course_path, :id=>"open-contacts-dialog-btn", :class=>"inbox-sf-add-btn tip" %>
What if I want to add a ruby variable and some normal text the button? e.g. $25,- (where the $ and ,- are fixed and the 25 variable...I am quite new to this...sorry if this is too easy, but struggling. I tried a lot of options and googled for long time.
The correct helper you want for this is button_to.
To use a variable in the button text is defined as string iterpolation. In your example it could be something like:
<%= button_to "$#{cost}", new_admin_course_path %>
Check out the button_to api reference for more options.
you could do like
amount = 25 #amount is the ruby variable
<%= link_to "<button>Add $#{amount}</button>".html_safe, new_admin_course_path, :id=>"open-contacts-dialog-btn", :class=>"inbox-sf-add-btn tip" %>
and I personally dont add <button></button> to the link and I rather use CSS to get the look and feel
Put your link inside a <button></button> tag. It'll be more readable.
And use variables interpolation in double-quoted strings to insert variable's value into string (the #{#variable_name} part)
<button>
<%= link_to "$#{variable_name}", new_admin_course_path, :id=>"open-contacts-dialog-btn", :class=>"inbox-sf-add-btn tip" %>
</button>

Serialized attributes not evaluating properly with form helpers

I'm rendering a form with serialized attributes. The attribute serialization works fine under normal usage, but now i'm trying to serialize a hash. The view code looks like the following
<%= #item.seasonality_of_sales_pct.each do |key, value| %>
<%= eval("f.label :'seasonality_of_sales_pct[:#{key}]'") %>
<%= eval("f.text_field :'seasonality_of_sales_pct[:#{key}]'") %>
<% end %>
The error I'm getting is undefined method 'seasonality_of_sales_pct[:January]' for #<Item:0x007f01083edd38>. However, the line that is throwing the error is the second eval. The first eval evaluates just fine. I'm baffled as to why this might be happening.
In the controller, I am setting up an attribute like the following
#item.seasonality_of_sales_pct = {January: nil, February: nil, March: nil, September: nil}
Another question that could maybe be answered in the comments is: How bad does this code smell? I'm not sure how the rails community feels about metaprogramming like this. It hurts me a bit to do it, but seems to work most of the time
When you use form_for and then use f.text_field :some_attribute_name then the object you are building the form for (in your case #item) mush have an attribute named some_attribute_name.
You get this error because #item has no attribute or method named seasonality_of_sales_pct[:January]
I also would point out that there is no reason to use eval in your form, it is a serious security risk, as code can be injected.
I wanted to be a bit more thorough than Khaled's answer, which was sort of right. The reason that the first eval statement didn't cause the error was because f.label doesn't care what you give it. <%= f.label :fake_stuff %> will just create a label called Fake Stuff. I'm still not quite sure why the attribute didn't work. If I had f.text_field :seasonality_of_sales_pct, I got a text box full of my hash. Also, I got the labels to display the correct values.
I absolutely did not need to use evals here (I can hope it was only a moment of weakness). Just do
<%= f.text_field :'seasonality_of_sales_pct[:"#{key}"]' %>

How would I add a method to ActiveView::Helpers::FormHelper to be used with form_for?

I am currently making a plugin, and I would like to add a method to ActiveView::Helpers::FormHelper, Essentially, the plugin is a helper that will convert checkbox input into bitwise flags so when you do actions like new and update, you can continue to pass in a params hash, and my plugin will pull out the checkbox data and convert it into a single number representing the flag state. Anyway, I want to be able to do something like this:
<% form_for #person do |f| %>
<%= f.check_boxes_for_flags %>
<% end %>
Which would create checkboxes in the HTML and then set them accordingly to the flags. I know how to add an instance method to ActiveView::Helpers::FormHelper, but I'm not sure how to access #person from this method. Any ideas?
Why wouldn't you use:
<%= f.check_boxes_for_flags :country %>
That way you can create your extension similar to how the ActiveView helpers work.
Take a look at how check_box_tag in the rails source code gets the name from the model. Try to follow the conventions set forth by the framework, it makes things easier for you and those who will maintain your code after you.

Should I use Response.Write directly from a View?

I have been trying to avoid using Response.Write(...) directly in my MVC Views. The reason being that I just need to type the string literals and the view engine knows what to do. However, in certain circumstances I seem to be creating way too many pointy brackets (<% %>). So, which of these 2 code snippets do you find more acceptable?
<% if (true)
{
Response.Write(Model.SomeValue);
} %>
Or
<% if (true) { %>
<%= Model.SomeValue %>
<% } %>
This is why Html Helpers exist (to avoid spaghetti code as much as possible):
<%= Html.MySuperHelper(Model.SomeValue) %>
Every time you need write an if statement in a view you might ask yourself the question: wouldn't it be better to write a helper method (which as a bonus could be unit tested) instead?
How about a third possibility?
<%= condition ? Html.Encode(Model.SomeValue) : "" %>
Although in practice you should keep all but the very simplest logic out of your view altogether. Either do the work in your controller or wrap the logic up in a HTML helper of some kind.
Or a fourth:
<%= condition ? Html.Encode(Model.SomeValue) : "" %>

Rails: Fields_for without a scope?

Is there a way to use fields_for with in a form without having a scope?
For example:
<% fields_for "user[]" do |x|
<%= x.text_field :name %>
<% end %>
Without the user model being loaded in memory?
I got it working using territory[user][][name], but I would like to keep it in ERB.
I think the answer would be 'no', since those form_for and fields_for would try to determine default value from that given instance variable.
However, I think if you want to lower memory usage from loading that model, you might try to create a mock-up model to return nil values, and create a instance object from that one instead.
is there any specific reason you need to use form_for specifically? Its really designed to be used with an instantiated model object.
Alternatively, why don't you just use the regular form helper tags. You can define it as follows:
<%form_tag :my_form do %>
<%= text_field_tag :foo, :bar %>
<%end%>
You may want to check the documentation for action view to see how it all works.

Resources