Rails Parse Form Input - ruby-on-rails

I'm using a form to transfer some data from one part of a controller to another (new to create), but I'm having some trouble with it. When I try to get the data after submitting the form, it just gives me a nil value.
Here's the form code:
<%= f.hidden_field :owner_id, :value => #tool.user_id %>
<%= f.hidden_field :tool_id, :value => #tool.id %>
<%= f.hidden_field :borrower_id, :value => current_user.id %>
And this is the create action in the controller:
def create
render text: params[:rental_agreement].inspect
#rental_agreement = RentalAgreement.create
#rental_agreement.owner_id = params[:owner_id]
# render text: #rental_agreement.inspect
end
When I hit the "Submit" button on the form, I see this:
{"owner_id"=>"3", "tool_id"=>"1", "borrower_id"=>"4"}
That's fine, but when I change which inspection renders (comment out the top line, uncomment the bottom), all it displays is:
#
And if I look in the Rails console at this object, all of the fields in it are nil (except the id and created_at fields).
I'm just trying to figure out how to assign the variables from the form (owner_id, tool_id, and borrower_id) to the rental_agreement variable. Any help is much appreciated!

Your create method seems wrong. Try this.
def create
#rental_agreement = RentalAgreement.new(params[:rental_agreement])
#rental_agreement.save
end

Related

How do I get the value of a form.input in active admin (ruby on rails)

I am using the administration framework 'active admin' to build a RubyOnRails Application. I have a Dropdown Menu that looks like this in my form:
form do |f|
f.inputs do
f.input :art, as: :select, :include_blank => "Bitte wählen!", label: 'art', :collection => ["Fachobjekt", "Gruppe", "Externes Dokument"]
end
f.actions
end
Now in my controller I want to check the selected value. I tried:
controller do
after_save :update_object
def update_object(guid)
if params[:art].values == 'Fachobjekt'
# do stuff
end
end
end
I chose 'Fachobjekt' in my Dropdown but I get the NoMethodeError "undefined method 'values' for nil:NilClass", so the params[:art] is null.
My question is: what is the correct syntax to get the selected value of my f.input-field? I appreciate any hint!
[:root_tables] ist the model name. I put it before [:art] like params[:root_tables][:art] but same error.
Put a
raise params.inspect
just before the
if params[:art]
line. You should be able to identify where the posted information resides in the params.
Thanks for all of your hints! Especially the hints for debugging with binding.pry helped me. I use f.select instead of f.input now:
form do |f|
f.inputs do
f.select :art, ["Fachobjekt", "Gruppe", "Externes Dokument"], :prompt => 'Bitte wählen! '
end
f.actions
end
For select the params[:root_table][:art] is working:
controller do
after_save :update_object
def update_object(guid)
if params[:root_table][:art] == 'Fachobjekt'
# do stuff
end
end
end
When i use f.input, [:art] is not even showing up when doing binding.pry or raise params.inspect.
With f.select it does.
However, at least it's working now, so thanks!

How to extract info from input field in ruby

I'm a frontend + PHP dev, trying to fix [] in a project built in Rails.
[] = Fetch color, show a slightly darker color.
This row:
<%= f.text_field attribute %>
creates an input field with a value that can be translated into a color. I'm at loss as to where to look for how it adds that value. I'm trying to use the value that this input field generates.
this is code from the file select_a_color_input.html.erb inside the app/views/shared folder. Any ideas on where to continue my treasure hunt? :)
update: I found this!
def app_text_field(attribute, args = {})
render_field 'text_field', field_locals(attribute, args)
end
Does that help? ^__^
update:
The form builder
class AppFormBuilder < ActionView::Helpers::FormBuilder
def form_fields(partial = nil , options = {})
partial ||= 'form'
fields = ''
unless options.delete(:without_error_messages)
fields << #template.render('shared/error_messages', :target => Array(#object).last)
end
fields << #template.render(partial, options.merge(:f => self))
end
def app_text_field(attribute, args = {})
render_field 'text_field', field_locals(attribute, args)
end
def app_file_field(attribute, args = {})
render_field 'file_field', field_locals(attribute, args)
end
private
def render_field(name, locals)
#template.render field_path(name), locals
end
def field_locals(attribute, args = {})
help_options = args[:help_options] || {}
field_options = args[:field_options] || {}
html_options = args[:html_options] || {}
{ :f => self, :attribute => attribute, :help_options => help_options, :field_options => field_options, :html_options => html_options, :object => object }
end
def field_path(value)
"shared/app_form/#{value}"
end
end
update:
When I tried to add
<%= content_tag(:p, attribute) %>
It does not give me the values, but instead the id/name of the item, not the colour.
<%= f.text_field attribute %>
This by itself is not very useful to help us gather context. What's the surrounding markup look like? attribute is a ruby variable in this instance. If it were f.text_field :attribute, then :attribute is now a symbol instead of a variable and this would indicate that it maps to the attribute method on X model. This all depends on what your form_for looks like though. I'll give an example:
<%= form_for #user do |f| %>
<%= f.text_field :attribute %>
In this case, we have a form for the User model, and our text_field maps to #user.attribute. The field itself looks something like this:
<input type='text' name='user[attribute]'>
And in the controller's #update or #create action (depending on if this is a new record or an existing record you're editing) the value would be accessible in this fashion:
params[:user][:attribute]
However, it's impossible to say what exactly the params will look like in your particular case. What action is being run? What's the name of the file that this is being loaded from? "app/views/users/new" would indicate the #new action handles this page, and the #create action will handle the form submission.
Things we need to know to fully solve your problem:
Name and relevant code of the controller that's handling this action.
Full view path that this is being rendered from
The rest of the markup starting at form_for and ending at this field attribute
What value does attribute hold? It's a variable, so it must be holding a symbol value or something that will indicate which field is being mapped to this input.

Accept Rails model attribute only if it was previously blank

I have a Rails model (persisted with Mongoid) that can be collaboratively edited by any registered user. However, I want to allow editing any particular attribute only if it was previously blank or nil.
For example, say someone created an object, and set its title attribute to "Test Product". Then another user comes along and wants to add a value for price, which until now has been nil.
What's the best way to do this, while locking an attribute that has previously been entered?
Look into the ActiveRecord::Dirty module for some nice utility methods you can use to do something like this:
NON_UPDATABLE_ATTRIBUTES = [:name, :title, :price]
before_validation :check_for_previously_set_attributes
private
def check_for_previously_set_attributes
NON_UPDATABLE_ATTRIBUTES.each do |att|
att = att.to_s
# changes[att] will be an array of [prev_value, new_value] if the attribute has been changed
errors.add(att, "cannot be updated because it has previously been set") if changes[att] && changes[att].first.present?
end
end
The easiest way, i think, is by checking for it in the form itself.
Just say add :disabled => true to the input field if the person cannot edit it.
<% if #my_object.name %>
<%= f.text_field :name, :disabled => true %>
<% else %>
<%= f.text_field :name, :disabled => true %>
<% end %>
(i think there is a prettier way to write this code)
But by using this the user has a visual feed back that he can't do something, it is always better to not allor something than to give an error message

Rails: embedding and retrieving array from form

I'm getting tripped up in Ruby, Rails & HTML syntax. Hoping some Rails ninja can help me with what's likely a trivial problem....
Post has_many Photos
Photo has a string :image attribute
In Post's _form.html.haml I would like to embed (in a hidden_field) the contents of the image attribute for each Photo associated with a Post...and then get it back out when form is submitted. I could do this either by A) adding one hidden_field for each photo.image or B) create a single array containing all associated photo.images.
I'm tripped up by how best to embed this...(A) or (B) neither of which I've fully perfected.
# _form.html.haml:
= form_for #post do |f|
- if #post.photos.any?
- #post.photos.each do |photo| -# (A)
= f.hidden_field :image_cache -# (A)
= f.hidden_field :images_cache -# (B)
= f.file_field :photos, :multiple => true
.actions
= f.submit 'Save'
#post.rb (A)
def image_cache
self.photos.any? ? photos.first.image : nil -# works with `first`
-# but not sure how to
-# pass id of others?!?
end
#post.rb: (B)
def images_cache
photos.map { |i| i.image }
end
Problem with (A) is I don't know how to pass the photo back to the Post model to return the image_cache attribute off of it?!? f.hidden_field :image_cache(photo) doesn't work
Problem with (B) is the images_cache returned by the Post model is an array but once embedded in the HTML page and returned by the following post request it has become a string representation of an array: [/uploads/tmp/20110729-1216-15902-2013/Before_Green_Flash.JPG, /uploads/tmp/20110729-1216-15902-5934/Before_Green_Flash2.JPG] and therefore does not respond to each.
Any help with either or both situations would be greatly appreciated!
For approach a, why not: = f.hidden_field photo.image

Retain Search Form Data Ruby On Rails

Trying to build a search on my homepage with simple_form (Pretty much same as formtastic). The search works fine and im getting my results but after submission I want to retain the vales with what the user submitted.
I am using a namespace for my form so how can I retain the data for the form. Here is some code which may help.
Controller
def index
#results = Property.search(params[:search])
end
View
%h1 Search Form
= simple_form_for(:search) do |f|
= f.input :location, :as => :select, :collection => Location.all.asc(:name)
= f.input :type, :collection => PropertyType.all.asc(:name)
= f.input :bedrooms, :collection => 1..10,
%p.box
= f.button :submit
-if #results
%h1 Search Results
.results
- #results.each do |property|
.result
%h1= property.title
Within the Index controller I have tried all sorts of things ie
#search = params[:search]
But each time I try something the search breaks.
What am I doing wrong ?
Hope you can advise
One approach is to do as Xavier Holt suggested, and pass in values to each input. The simpleform doco suggests:
= f.input :remember_me, :input_html => { :value => '1' }
The other approach is to have simpleform do it for you. SimpleForm will automatically populate the fields with values if you give it something like an activerecord object.
In this case, that means creating a model object:
class PropertySearchCriteria
attr_accessor :location, :type, :bedrooms
def initialize(options)
self.location = options[:location]
self.type = options[:bedrooms]
self.bedrooms = options[:bedrooms]
end
end
Then, change your controller:
def index
#property_search_criteria = PropertySearchCriteria.new(params[:search])
#results = Property.search(#property_search_criteria)
end
(you'll have to change the Property.search method as well)
Then, change your simple_form_for:
= simple_form_for(:search, #property_search_criteria) do |f|
And if you do all that, and get the stars to align just right, then simpleform will pre-populate the form fields all by itself. You may have to add some stuff to PropertySearchCriteria to get simpleform to be properly happy.
This is a lot of stuffing around just to get the values showing up, but it'll keep you sane if you need to add validations.
I'm doing something similar in the app I'm working on (I'm not using formtastic, but this should be at least very close to something that works for you). I got around it by making sure #search was a hash in the controller:
#search = params[:search] || {}
And then using #search[:key] as the :value option in all my search inputs (There's a chance you'll need to set #search.default = '' to get this working):
<%= text_field_tag :name, :value => #search[:name] %>
And that's all it took. As my app is getting more complicated and AJAXy, I've been thinking of moving the search parameters into the session information, which you might want to do now to stay ahead, but if you're just looking for a simple solution, this worked great for me.
Hope this helps!
you can try storing your parameters in session like so:
def index
#results = Property.search(params[:search])
store_search
end
def store_search
session[:search] = params[:search]
end
just be sure when you are done with the parameters that you clean them up
...
clear_search if session[:search]
def clear_search
session[:search] = nil
end

Resources