Label will display but not text_field - Rails - ruby-on-rails

I'm working on my first rails app and having a weird issue.
I'm using Rails 3.2.6 with mongodb.
In my view, I can get a label to display like so:
<%= f.label :percent %>
But when I try the same thing with a text field
like so:
<%= f.text_field :percent %>
the page doesn't even load, nothing happens.
Here is my controller:
class TrimmingsController < ApplicationController
def new
#order = Order.find params[:order_id]
end
And my model:
class Trimming
include Mongoid::Document
embedded_in :order
field :percent, type: String
end
And here is my whole view:
<%= form_for #order do |f| %>
<p>
<%= f.text_field :percent %>
</p>
<% end %>
I just want to get a text_field to display sorry for the
simpleton question but I've been trying for 2 days to get
this text field to pop up.

You need to make percent attr_accessible. Add this to your model.
attr_accessible: :percent

Check it with following code in view:
<%= form_for :order do |f| %>
<%= f.text_field :percent %>
<% end %>

Related

Rails, use a form field to set something on the user registration (devise)

I would really like to add a form field "invite_code" to the user sign up form, but I don't know how to add the invite_code to the controller so that the application knows how to look for it?
The form in the sign up on the template would read:
<% form_for User.new do |f| %>
<span>Email:</span> <% f.email %><br>
<span>Name:</span> <% f.name %><br>
<span>Invite Code:</span> <% f.invite_code %><br>
<% end %>
The "invite_code" isn't part of the database or anything, but in the user registration model, I want to put a:
before_save :invite_promo
def invite_promo
if #invite_code.present? && #invite_code == "special_person"
self.special_key = true
end
end
Is there an easy way to look for form fields in the template using the model or controller?
So sorry...I'm new to Rails. Thank you so much in advance!
You need to define a virtual attribute invite_code in User model:
attr_accessor :invite_code
Your form should look as follows:
<%= form_for User.new do |f| %>
<span>Email:</span> <%= f.email_field :email %><br>
<span>Name:</span> <%= f.text_field :name %><br>
<span>Invite Code:</span> <%= f.text_field :invite_code %><br>
<% end %>
if you don't want to create a field inside your table, you can use hidden field in view like, <%= hidden_field_tag :invite_code, 'code' %>

Given a Model enum, how to create a radio button group

I have a model like:
class User < ActiveRecord::Base
enum :status [:banned, :registered, :trial, :pending]
end
On my edit page, I want to show a list of 4 radio buttons and pre-select the radio button that is currently set for a user.
How can I do this?
<%= form_for #user do |f| %>
<%= f.collection_radio_buttons :status, User.statuses, :first, :first %>
<%= f.submit %>
<% end %>
Ref
Rails creates a class method using the pluralized attribute name when you use enum. The method returns a key value pair of strings you've defined and what integers they map to. So, you could do something like this:
<% User.status.keys.each do |status| %>
<%= f.radio_button :status, status %>
<%= f.label status.to_sym %>
<% end %>

In Rails with Globalize, update seems to ignore empty string fields

I am very new to Rails and I am facing a somehow weird problem, and my googling didn't helped me so far...
I have implemented a classical CRUD ressource following the Getting Started with Rails guide and I am blocking on the "update" part:
http://guides.rubyonrails.org/getting_started.html#updating-articles
This is part of my model "Devwork":
class Devwork < ActiveRecord::Base
validates :short_title, presence: true, uniqueness: true
validates :title_fr, presence: true, allow_blank: false
translates :title, :summary, :description
globalize_accessors
end
I am using the Globalize gem to persist localized data, and Globalize-accessor for the helpers.
Here is the controller's update action:
class DevworksController < ApplicationController
def update
#devwork = Devwork.find(params[:id])
if #devwork.update(devwork_params)
redirect_to #devwork
else
render :edit
end
end
private
def devwork_params
params.require(:devwork)
.permit!
end
end
And part of the form:
<%= form_for #devwork do |f| %>
<p>
<%= f.label :short_title %>
<%= f.text_field :short_title %>
</p>
<p>
<%= f.label :title_fr %>
<%= f.text_field :title_fr %>
<%= f.label :title_en %>
<%= f.text_field :title_en %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
short_title and title_fr are mandatory, while there exist another field title_en which is not. I want the update form to be shown again if the update fails (typically because of empty title_fr).
But it doesn't work. The update never fails (never entering render :edit) even if title_fr is empty. In fact, the update does nothing if one of the field is empty, it only updates non-empty fields.
I surely missed something somewhere, but I can't figure it out... perhaps a missuses of Globalize ?
Thanks for your help !

Ruby on Rails: Multiple Input Fields in The Same Form - Change ID/Value

Have a page where there are multiple input fields of the same thing, Posts. Right now, when a user enters in a question for, let's say 3 fields, the only one that saves to the database is the last one. Whereas, it should save all three and give them each it's own post_id. Also; if the user doesn't enter anything in for the other fields, it should not save in the database either.
new_step_4_html.erb
<%= form_for(#post) do |f| %>
<%= f.text_field :content %>
<%= f.text_field :content %>
<%= f.text_field :content %>
<% end %>
projects_controller.rb
def new_step_4
#post = Post.new
end
Right now, all it does is submit one :content field, obviously because they all share the same id/value. Unfortunately, the Railscasts #197 applies for nested forms, so the javascript and helper stuff he does all applies for nested. I would think this is something simple. Person from IRC mentioned I could do some sort of '3.times' code into the view file or something?
First of all you will probably have to edit the model of you post.
post.rb
has_many :contents, :dependent => :destroy
accepts_nested_attributes_for :contents
You will need another model to store the content fields.
so first generate a model
rails g model content post_id:integer body:text
the model
content.rb
belongs_to :post
Now, in stead of doing <%= f.text_field :content %> a few times, let rails create them, because now you basically let them overwrite each other.
3.times do
content = #post.content.build
end
the form view will be something like this:
<%= form_for #post do |f| %>
<%= f.fields_for :contents do |builder| %>
<%= builder.label :body, "Question" %><br />
<%= builder.text_area :body, :rows => 3 %><br />
<%= end %>
<p><%= f.submit "Submit" %></p>
<% end %>
I did not test this code, but the idea should be correct. Let me know if you need more info.

Multiple forms for the same model in a single page

On the front page of my rap lyrics explanation site, there's a place where users can try explaining a challenging line:
alt text http://dl.dropbox.com/u/2792776/screenshots/2010-02-06_1620.png
Here's the partial I use to generate this:
<div class="stand_alone annotation" data-id="<%= annotation.id %>">
<%= song_link(annotation.song, :class => :title) %>
<span class="needs_exegesis"><%= annotation.referent.strip.gsub(/\n/, "\n <br />") %></span>
<% form_for Feedback.new(:annotation_id => annotation.id, :created_by_id => current_user.try(:id), :email_address => current_user.try(:email)), :url => feedback_index_path, :live_validations => true do |f| %>
<%= f.hidden_field :annotation_id %>
<%= f.hidden_field :created_by_id %>
<p style="margin-top: 1em">
<%= f.text_area :body, :rows => 4, :style => 'width:96%', :example_text => "Enter your explanation" %>
</p>
<p>
<% if current_user %>
<%= f.hidden_field :email_address %>
<% else %>
<%= f.text_field :email_address, :example_text => "Your email address" %>
<% end %>
<%= f.submit "Submit", :class => :button, :style => 'margin-left: .1em;' %>
</p>
<% end %>
</div>
However, putting more than one of these on a single page is problematic because Rails automatically gives each form an ID of new_feedback, and each field an ID like feedback_body (leading to name collisions)
Obviously I could add something like :id => '' to the form and all its fields, but this seems a tad repetitive. What's the best way to do this?
If you don't want to change your input names or your model structure, you can use the id option to make your form ID unique and the namespace option to make your input IDs unique:
<%= form_for Feedback.new(...),
id: "annotation_#{annotation.id}_feedback"
namespace: "annotation_#{annotation.id}" do |f| %>
That way our form ID is unique, i.e. annotation_2_feedback and this will also add a prefix, e.g. annotation_2_, to every input created through f.
Did you consider nested_attributes for rails models? Instead of having multiple new feedback forms where each is tied to an annotation, you could have multiple edit annotation forms where each annotation includes fields for a new feedback. The id's of the generated forms would include the annotations id such as edit_annotation_16.
The annotation model would have a relationship to its feedbacks and will also accept nested attributes for them.
class Annotation < ActiveRecord::Base
has_many :feedbacks
accepts_nested_attributes_for :feedbacks
end
class Feedback < ActiveRecord::Base
belongs_to :annotation
end
You could then add as many forms as you want, one for each annotation. For example, this is what I tried:
<% form_for #a do |form| %>
Lyrics: <br />
<%= form.text_field :lyrics %><br />
<% form.fields_for :feedbacks do |feedback| %>
Feedback: <br/>
<%= feedback.text_field :response %><br />
<% end %>
<%= form.submit "Submit" %>
<% end %>
<% form_for #b do |form| %>
Lyrics: <br />
<%= form.text_field :lyrics %><br />
<% form.fields_for :feedbacks do |feedback| %>
Feedback: <br/>
<%= feedback.text_field :response %><br />
<% end %>
<%= form.submit "Submit" %>
<% end %>
And the quick and dirty controller for the above edit view:
class AnnotationsController < ApplicationController
def edit
#a = Annotation.find(1)
#a.feedbacks.build
#b = Annotation.find(2)
#b.feedbacks.build
end
def update
#annotation = Annotation.find(params[:id])
#annotation.update_attributes(params[:annotation])
#annotation.save!
render :index
end
end
I had this same issue on a site I'm currently working on and went with the solution you mention at the bottom. It's not repetitive if you generate the ID programmatically and put the whole form in a partial. For example, on my site, I have multiple "entries" per page, each of which has two voting forms, one to vote up and one to vote down. The record ID for each entry is appended to the DOM ID of its vote forms to make it unique, like so (just shows the vote up button, the vote down button is similar):
<% form_for [entry, Vote.new], :html => { :id => 'new_up_vote_' + entry.id.to_s } do |f| -%>
<%= f.hidden_field :up_vote, :value => 1, :id => 'vote_up_vote_' + entry.id.to_s %>
<%= image_submit_tag('/images/icon_vote_up.png', :id => 'vote_up_vote_submit' + entry.id.to_s, :class => 'vote-button vote-up-button') %>
<% end -%>
I also had the same issue but wanted a more extensible solution than adding the ID to each field. Since we're already using the form_for ... |f| notation the trick is to change the name of the model and you get a new HTML ID prefix.
Using a variant of this method: http://www.dzone.com/snippets/create-classes-runtime (I removed the &block stuff)
I create a new model that is an exact copy of the model I want a second form for on the same page. Then use that new model to render the new form.
If the first form is using
#address = Address.new
then
create_class('AddressNew', Address)
#address_new = AddressNew.new
Your ID prefix will be 'address_new_' instead of 'address_' for the second form of the same model. When you read the form params you can create an Address model to put the values into.
For those stumbling here, looking for the solution for Rails 3.2 app, look at this question instead:
Rails: Using form_for multiple times (DOM ids)

Resources