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.
Related
I have a class that I'm using STI with to provide unique, per-type logics. I do not want to create forms and controllers for each unique type, I want to leverage inheritance and have a single controller using the superclass, Package, with the subclasses not even being referenced (at this stage).
The new 'form_with' helper handles 99% of cases for me, but in this case the below code doesn't work. It throws an error because #package is a subclass of the core Package class, and that subclass doesn't have routing information. I need it to map the Package class and associated controllers instead.
<%= form_with(model: [#show, #package], local: true) do |form| %>
# Form Data Here
<% end %>
<%= form_with(#package.becomes[Package]) do |form| %>
# Form Data Here
<% end %>
This solution seems a little hackey, but it's the best I've been able to come up with. I suspect that it may be the best, absent form_with having some specific code to handle / recognize STI that I couldn't find documentation for.
<%= form_with(url: show_packages_path(#show,#package),scope: 'package' ,model: [#show, #package], local: true) do |form| %>
# Form data Here
<% end %>
By using the show_packages_path helper, I'm able to forcibly scope the route to a specific route. It's not as clean and flexible, but the extra code is there specifically to handle STI. The same for the scope key, which re-scopes the form so it doesn't try to nest all the params under the subclass name instead of the superclass name.
I have two models - Client & Topic, with a HABTM relationship between them.
I am trying to generate a series of checkboxes of the topics, on the Client form partial.
This is what I am doing:
<% Topic.all.each do |topic| %>
<% checked = #client.topics.include?(topic) %>
<%= f.label(:name, topic.name) %> <%= f.check_box #topics, topic.id %>
<% end %>
This is the error I get:
undefined method `merge' for 1:Fixnum
I know one solution is to use check_box_tag, but that forces me to do the record updating of the associations manually.
So I would rather use the form_helper for the checkbox tag. The docs are a bit confusing to me.
How can I get this to work with f.check_box.
Thanks.
The code confuses me. What #topics contains? If it's a collection of of Topic then why you are directly accessing Topic model in the view? It would be:
#topics.each.do
rather than you
Topic.all.each
Moreover, you are using #topics as collection inside a loop. How check_box will generate checkbox from a collection?
Please look at the following things:
accepts_nested_attributes_for. you will need this to set in Client model in addition to Client has_many Topic association
fields_for Otherwise, rails will not have any idea that you want to update topic model from this same form.
Check this screencasts to get an idea how you can make it work
For whatever reason, the form helper doesn't work with check_box.
So, this is the code that works:
<%= check_box_tag "client[topic_ids][]", topic.id, checked %>
According to other answers for similar questions, the helper f.check_box is model bound and the value supplied to the checkbox is implicit from the model on the form. The issue is, I can't figure out how to get the implicit value of the form_helper to produce the correct tag - i.e. client[topic_ids][], so I have had to resort to check_box_tag.
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.
Is there a way to send an extra parameter through a form in rails 3?
For example:
<%= form_for #post do |f| %>
<%= f.hidden_field :extraparam, :value => "22" %>
<% end %>
but lets say :extraparam isn't part of the post model..
I have an unknown attribute error in the create method of the controller when I try this, any ideas?
(I want to use the param value itself in the controller for some extra logic)
Call hidden_field_tag directly. See: http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-hidden_field_tag
These helpers exist for all the major form field types, and are handy when you need to go beyond your model's methods.
The following worked for me in passing extra parameters from the view back to the controller that were a part of my model and not part of my model.
<%= hidden_field_tag :extraparam, value %>
Example usage
<%= hidden_field_tag :name, "John Smith" %>
Ya Paul is right. Hidden_field is associated with your model whereas the extra _tag fields are not. I'm not sure of your needs but It's generally recommended in the RoR community to avoid passing a ton of hidden_fields like you might do in a php application.
Ive seen some code where ids were getting passed around in hidden fields which rails takes care on its own if you know the best practices and take full advantage of the framework. Of course I'm just saying this as general info as there are sometimes better ways at accomplishing the same functionality. Good luck on your apps.
we use
(1..10).each do |i|
p i
end
so that a value is "yield" to i in a block...
but what about
<% form_for #story do |f| %>
<%= f.text_field :name %>
<% end %>
there is no loop at all... why do we need to make it look like a loop? Can't we do it without making it look like a loop? (write in another way)?
Also, must be use a Story instance here? Can't we just use :story and achieve the same result? The #story instance is just newly created and has no data at all -- does it actually help creating the form? Can't :story suffice already? thanks.
Update:
is the idea similar to: (just pseudo code)
with_model_give_form (#story) do |f|
f.begin_form
f.text_field :name
f.end_form
end
so i think the block method will save the begin_form and end_form because it automatically add the begin and end before and after calling the block. is that the main benefit?
I think you have misunderstood the way Ruby works in this case.
It is true that you put everything in a block, but it has nothing to do with a loop.
What you actually do in
(1..10).each do |i|
p i
end
is creating the block {|i| p(i); } and sending it to the function Range.each()
It is the same thing with the form_for. What you actually do is creating the block {|f| puts( f.text_field(:name)); } and passing it to the form_for function. (now it doesn't use puts, but some string concatenation, but you get the idea).
So it's basically not a loop, but a lambda function that will be called several times when called in a loop.
Here is some more information about blocks
Update:
Regarding your update. In a way, yes, that is the main benefit. It is not completely true, but you get the idea. The purpose for that block (and a lot other) are to make the code easier to read and understand. And also to speed up the development.
Dividing code into blocks have always been sought for, just look at the concept of functions, classes and other statements.
for instance, the form_for is mostly for speeding up the development. Yes, it creates the start and end tags, but that is not all.
<% form_for #story do |f| %>
<%= f.text_field :name -%>
<% end %>
Could actually be written something like:
<form action="<%= polymorphic_edit_path(#story) -%>"
id="<%= #story.class_name.underscore -%>">
<%= text_field :story, :name -%>
</form>
of course, it wouldn't exactly be like that, this is a lot simplified and the form_for function can do a lot more than that, but at least you should get the picture.
A "yield" does not always imply a loop - it's more of a "block" concept, it just happens to manifest itself in more of a iteration / loop context. The more you think about yield being a loop construct the more you pigeon hole yourself and prevent yourself from truly learning the awesomeness of blocks.
As for :story, yeah, it is kind of lame. You would think that Rails would just constantize it and infer its model from there. You could also just also Story.new in your view, versus doing that in your controller, but yeah, it's the same thing.