Rails form helper fails - ruby-on-rails

Ok this is my first app in rails so hopefully this is a simple problem.
Here is my object:
- !ruby/object:ProductImage
attributes:
image_id:
product_id:
created_at:
updated_at:
attributes_cache: {}
This works:
<%= image_form.text_field :product_id %>
But I get undefined method `image_id' for:
<%= image_form.text_field :image_id %>
I just don't get it...
Cheers for any help on this.
This is the actual partial:
<div class="image">
<% new_or_existing = product_image.new_record? ? 'new' : 'existing' %>
<% prefix = "product[#{new_or_existing}_product_image_attributes][]" %>
<% fields_for prefix, product_image do |i| -%>
<div class="input select">
<%= i.text_field :image_id %>
<%= link_to_function "remove", "$(this).up('.image').remove()" %>
</div>
<% end -%>
</div>
P.S a text field is being used just as an example

Can you post the entire form? I have a hunch that maybe you did:
<% form_for :image do |image_form| %>
instead of:
<% form_for :product_image do |product_image_form| %>
Of course, I'd rethink displaying a form where people are manually entering id values in order to join an image to a product, but I understand you're in learning mode right now.

ID fields should not be text_fields, they should be checkboxes or drop-down select boxes. Why would your use know what the Rails ID is?

Related

Rails 5 fields_for only sends last params

I have been hitting my head against a brick wall so it is time to seek smarter people.
I am trying to create multiple records of one model using form_tag and fields_for. I have been following all the help/issues/guides I can find but it doesn't seem to work for me. I am wondering if it something that changed going to Rails 5 but more likely it is me.
Basically I want a new/create version of the task system listed at the bottom of the api page, similar to this guys puppy creator.
The "new" page loads fine with as many records as I like, so that part is ok but it doesn't seem to be creating a collection to send through, it is just overriding and thus sending through the last set of params so only creating one record.
What I have.
# routes
resources :container_returns
controller
# container returns controller
def new
#containers = Container.where(id: params[:container_ids])
#container_returns = []
#containers.each do |container|
#container_returns << ContainerReturn.new(
{
container_id: container.id,
quantity: container.amount,
uom: container.uom,
material_restriction_id: container.material_restriction_id
}
)
end
end
view
# new.html.erb
<%= form_tag container_returns_path, method: :post do %>
<% #container_returns.each do |container_return| %>
<%= fields_for 'returns[]', container_return, hidden_field_id: true do |cr| %>
<div class="field">
<%= cr.label :container_id %>
<%= cr.number_field :container_id %>
</div>
<div class="field">
<%= cr.label :material_restriction_id %>
<%= cr.number_field :material_restriction_id %>
</div>
<div class="field">
<%= cr.label :quantity %>
<%= cr.text_field :quantity %>
</div>
<div class="field">
<%= cr.label :uom %>
<%= cr.text_field :uom %>
</div>
<% end %>
<% end %>
<%= submit_tag "lots of returns" %>
<% end %>
which submits
# params submitted
Started POST "/container_returns" for 127.0.0.1 at 2018-10-19 11:00:48 +0200
Processing by ContainerReturnsController#create as HTML
Parameters: {
"utf8"=>"✓", "authenticity_token"=>[removed],
"returns"=>{"container_id"=>"405", "material_restriction_id"=>"", "quantity"=>"100.0", "uom"=>"kg"}, "commit"=>"lots of returns"
}
hopefully it is just something stupid that I missed.
UPDATE:
if I add an index to the form it now believes me that my objects are different and sends through all the params I need.
<% #container_returns.each_with_index do |container_return, index| %>
<%= fields_for 'returns[]', container_return, index: index do |cr| %>
[...]
as mentioned in the update, if I add an ID to the initial create it builds the correct array that I was expecting. What I also found was if I send through an index position that also works.
<% #container_returns.each_with_index do |container_return, index| %>
<%= fields_for 'returns[]', container_return, index: index do |cr| %>
[...]
gives me what I was expecting
Parameters: {
"returns"=>{"0"=>{"container_id"=>"400",...},
"1"=>{"container_id"=>"401",...},
etc.
},
"commit"=>"lots of returns"
}

Adding user's photo to contest, call method with link_to

I came from a JS background so Rails is weird to me. I currently have a show.html.erb for the contest model:
<h1>Contest name: <%= #contest.name %></h1>
<h2>Contest criteria: <%= #contest.criteria %></h2>
<h3>Photos: </h3>
<%= link_to "Enter Contest", "#" %>
<% #contest.photos.each do |photo| %>
<%= image_tag("#{photo}") %>
<% end %>
With the link_to I'm trying to render all photos that belongs to the current_user and pick one of them to assign it to the current contest. The params passing seems all so mysterious to me. Can you guys point me in the right direction of how I should tackle this problem? Thanks
What I understand you need to select an image from list of images and pass the id. So, try this
<%= label_tag "Enter Contest" %>
<% #contest.photos.each do |photo| %>
<%= link_to (image_tag("#{some photo path}")), some_controller_method_path(:photo_id => photo.id) %>
<% end %>
And in controller you can use params[:photo_id]

When using rails Action View Helpers - how can you customize the params to be an Array of the labels?

I have this view
...code....
<% #feeds.each do |feed| %>
<%= check_box_tag(feed.name) %>
<%= label_tag(feed.name) %>
<% end %>
...code....
The Feed model looks like this
Feed(id: integer, name: string, description: string, url: string, created_at: datetime, updated_at: datetime, day_selector: string, special_selector: string)
and the submission comes into the params hash like this
{"utf8"=>"✓",
"authenticity_token"=>"WVbxZckIJCA0dXqPZGnSXJi7yrDN3Ssttv7dnJZOfBY=",
"email"=>"",
"phone_number"=>"",
"Squeaky Beaker"=>"1",
"Commonwealth Cambridge"=>"1",
"commit"=>"GO",
"action"=>"create",
"controller"=>"subscriptions"}
I want the params hash to look this this
{:feeds => {'Squeaky Beaker' => 1, 'Commonwealth Cambridge' => 1}}
or just simply
[{'Squeaky Beaker' => 1, 'Commonwealth Cambridge' => 1}]
How can I customize my view to have the params hash look the way I want?
untested, but you could try...
<ul>
<% #feeds.each do |feed| %>
<li>
<%= check_box_tag 'feeds[]', (feed.name => 1) -%>
<%= h feed.name -%>
</li>
<% end %>
</ul>
I'm not sure the => 1 has value to your application, so the more traditional approach would be
<%= check_box_tag 'feeds[]', feed.name -%>
interpreted from the documentation at http://apidock.com/rails/ActionView/Helpers/FormTagHelper/check_box_tag
Check Box
To further SteveTurczyn's answer, what you're basically doing right now is outputting two checkboxes (completely different to each other), which will both hold a value of "1" (checked):
<% #feeds.each do |feed| %>
<%= check_box_tag(feed.name) #-> feed.name will be different each time %>
<%= label_tag(feed.name) %>
<% end %>
You'll need to give the check boxes the same name, as to give Rails the ability to discern their values being different. And secondly, you'll need to ensure you have the correct vales / options for the boxes too:
<% #feeds.each do |feed| %>
<%= check_box_tag "feeds[]", feed.name %>
<% end %>
This will pass the parameters as follows:
["checked_value_1", "checked_value_2"]
If you use the names of the feeds, it will give you:
["Feed1", "Feed2"] #-> names
["5", "6", "7" ] #-> ids

Passing variable param in form via dropdown

I have this form:
<tr>
<% item.inventory_items.each do |product| %>
<td>
<%= form_tag("/list_items", method: "post") do %>
<%= hidden_field_tag(:item_id, item.id) %>
<%= hidden_field_tag(:inventory_item_id, product.id) %>
<%= hidden_field_tag(:shopping_list_id, ShoppingList.first.id) %>
<%= submit_tag("#{product.price}", class: "btn btn-primary") %>
<% end %>
</td>
<% end %>
</tr>
Currently the hidden_field for shopping_list_id is being set, as you can see, by ShoppingList.first.id. That was really just a placeholder to make sure my form was working. I want the :user to be able to select which of their lists to submit this list_item to. I'm unsure of the best way to do that. Ideally I'd like to be able to have them hover over the product price and have a drop down of their lists to select from, whereby the form would get the shopping_list_id from. How can I best accomplish something like this? I'm using Twitter Bootstrap. Thanks in advance.
Something like this should get you started:
<%= select_tag(#user, :shopping_list_id, options_for_select(#user.lists)) %>

Ruby on Rails: text filed

I have a code where a user can select a specific file to be deleted or analyzed.
<% if #files%>
<%= form_tag what_to_do_files_path, method: :get do %>
<%= submit_tag "Delete selected", :name => 'delete' %>
<%= submit_tag "Analyse", :name => 'analyse' %>
<% #files.each do |file| %>
<% if (file.analyzed=="no") %>
<p><td> <%= check_box_tag "files[]", file.id %></td><%= file.name %></p>
<% else %>
<div class="my_profile_info">
<p><td> <%= check_box_tag "files[]", file.id %></td> <%= file.name %></p>
<td class="Info">
Info
</td>
</div>
<% end %>
<%end%>
<%end%>
<%else%>
<%end%>
I need to be able to give a name to every analysis.
For example: user selects 3 files, enters a name in the text field "Analysis of annual profit" and clicks on the button "Analyse".
The name "Analysis of the annual profit" and the names of the files that were selected have to be saved into the table group_analysis.
I have tried something like this after submit_tag "Analyse":
<%= form_for #groupanalysis do |f| %>
<div class="field_label">
<%= f.label :group_name, "Type group name hier" %>
</div>
<br class="clear" />
<br />
<% end %>
but it tells me undefined method model name
Thanks in advance.
I think you may need to take a step back and think of how this form represents the model that you're trying to create or update. Generally speaking the first argument to form_for and form_tag is an object and symbol, respectively, which represent the model that you're working with. The form fields map to each attribute of the object.
According to conventions and/or the :url argument, this will get routed to the appropriate controller and call an action according to the HTTP verb (again, part of many conventions in rails).
Going back to your code examples, you are using the form_tag helper incorrectly and the example using form_for may not be the right implementation. For example you're just displaying a label, with no input nor submit.
I hate to just post a link here and just tell you to read the docs, but in this case I think this is the best first step.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for

Resources