i'm having a problem to create a text_field without a method association. Maybe i even don't need it :-)
I have two radio_buttons associated to the same method:
<%= radio_button :comment, :author, "anonymous" %> Anonymous <br>
<%= radio_button :comment, :author, "real_name" %> Name <br>
What i would like to do is to have an text_field which when the user click on the radio_button "real_name" i can verify the value in this new text_field.
Basically my Controller would be something like:
#comment = Comment.new(params[:comment])
if #comment.author == "real_name"
#comment.author = "value-from-the-new-textfield
end
There is any way to do it?
Regards,
Victor
If you want to generate a text_field without an associated object/method, use text_field_tag
You can use another parameter instead of :comment
<%= radio_button :verify, :author, "anonymous" %> Anonymous <br>
<%= radio_button :verify, :author, "real_name" %> Name <br>
So in your controller you can get the value of selected button with
if params[:verify][:author] == 'real_name' ...
text_field_tag is definitely the easiest way, but if you want to add a field that acts as part of a model, adding an attr_accessor attribute might be worth looking into as well.
Related
I have two models, Dog and Owner, and I want their names to be the same, and would be redundant if I asked to fill out the fields twice (once for the dog and another time for the owner). I'm wondering if there's a simpler way to update the two databases with one input.
<h1>Create a new Dog:</h1>
<%= form_for(#dog) do |f|%>
<div>
<%= f.label :name%>
<%= f.text_field :name%>
</div><br>
<div>
<%= f.label :breed%>
<%= f.text_field :breed%>
</div><br>
<div>
<%= f.label :age%>
<%= f.text_field :age%>
</div><br>
<div>
<h3>create a new owner:</h3>
<%= f.fields_for :owner, Owner.new do |owner_attributes|%>
<%= owner_attributes.label :name, "Owner Name:" %>
<%= owner_attributes.text_field :name %>
<% end %>
</div>
<%= f.submit %>
<% end %>
First of all, not sure why you want to keep the name of the owner and the dog same.
However, there can be many ways to achieve what you want:
You can simply omit the owner name from the form.
So you no longer need: <%= owner_attributes.label :name, "Owner Name:" %>
OR you no longer need:
<div>
<%= f.label :name%>
<%= f.text_field :name%>
</div><br>
And in the Owner/Dog model, you can pass the name of the dog/owner in a callback - maybe after_initialize or before_save or before_validation depending on your validation requirements.
class Dog
belongs_to :owner
before_validation :set_name
private
def set_name
self.name = owner&.name
end
end
You can make the owner name as a hidden field instead and can write some javascript to update the hidden field with the dog name before submitting the form or onblur event. I would prefer the first approach since it's simpler and more secure than only JS solution to maintain database consistency
If dogs belongs_to and owner, you don't really need to store the owner's name separately. You can just call dog.owner.name anywhere you have a Dog instance. Having said that, it is relatively straightforward to append attributes on top of the POSTed form values in your controller using .merge():
def create
#dog = Dog.new(dog_params.merge(owner: params[:dog][:owner])[:name])
if #dog.save
...
end
end
def dog_params
params.require(:dog).permit(:name, :breed, :age, owner: %i[name])
end
In the Rails Tutorial there is a great chapter on creating a toy app with users and microposts. However, when editing the microposts, I can only edit user_id which is a numeric value, not user name. Is there a simple way to enforce displaying user's name instead of user's id in the app?
I've looked app/views/microposts/_form.html.erb and it says:
<div class="field">
<%= f.label :user_id %><br>
<%= f.number_field :user_id %>
</div>
What should I change to be able to select the users by name instead of the id?
Try using a select helper rather than a number_field.
<%= f.collection_select(:user_id, #users, :id, :first_name) %>
In your controller, you'd need the following line (or something similar):
#users = User.all
If you want to display each user's full name, you'd need to create a method in user.rb to concatenate first and last names, like so:
def fullname
fullname = "#{last_name}, #{first_name}"
end
Your select would then use the method name, like this:
<%= f.collection_select(:user_id, #users, :id, :fullname) %>
You should probably take some time to read up on all the different form helpers.
The feature you're looking for is called a collection_select. http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select
f.collection_select :user_id, User.all, :id, :username
I'm using simple_form and I'd like to pre-populate several fields in my form. In the link to the form I'm passing several values to params in the URL. The trouble comes in when I either try to pass a value to a field that is an integer or an association. In either case, the field does not pre-populate.
Example below...the first two fields populate fine, but I had to force them to be text fields. Maybe that's ok to push the strings from the url into the field, but ideally I'd be able to use either the integer (f.input) or association (f.association). The second two fields don't pull in the param values from the URL.
Any ideas? Thanks in advance!
NOTE - this is for generating a NEW record in the database and not for editing an existing record.
URL: http://localhost:5000/list/new?event_id=4&user_id=11
<!-- These two fields pre-populate -->
<%= f.text_field :event_id, :value => params[:event_id] %>
<%= f.text_field :user_id, :value => params[:user_id] %>
<br>
<!-- These two fields do NOT pre-populate -->
<%= f.association :event_id, :value => params[:event_id] %>
<%= f.input :event_id, :value => params[:event_id], label: 'Event' %>
PS - I'm listening to GusGus' new album on Spotify while working on this and it's helping a lot. :)
Best practice is pre-populate form not with params directly but with ActiveRecord object.
For example you have an AR class:
class Party < ActiveRecord::Base
belongs_to :event
belongs_to :user
end
Then in your controller:
def new
#party = Party.new(party_params)
end
# use strong params to make your parameter more secure;)
def party_params
params.permit(:event_id, :user_id)
end
and then in your edit view:
<%= simple_form_for #party do |f| %>
<%= f.association :event %>
<%= f.association :user %>
<% end %>
I need to convert check_box_tag to f.check_box, but I am having trouble doing so.
My check box has
check_box_tag 'privacy', 1, (#idea.privacy=='private'), :id=>"Make Private"
So the name = 'privacy', value = 1, checked when (#idea.privacy=='private') is true, and has id "Make Private". Can anyone help me? Thanks!
You might want to add a virtual attribute to do this.
For example, in app/models/idea.rb:
class Idea < ActiveRecord::Base
attr_accessor :is_private
def is_private
privacy == 'private'
end
def is_private=(true_or_false)
self.privacy = true_or_false ? 'private' : 'public'
end
end
It can be used in a form like this:
<%= form_for(#idea) do |f| %>
<%= f.check_box :is_private %>
<%= f.submit %>
<% end %>
I suggest following the convention of Rails and use the generated id of the checkbox: idea_is_private.
If you intend to name it in different way, here is how you can do it:
<%= f.check_box :is_private, :id => 'make-private' %>
p.s. Most people do not use spaces in ids.
p.s.s. How the virtual attribute works:
f.check_box :is_private informs Rails of which methods should be used to read and write to the record. In this case, the value of the checkbox would be #idea.is_private. And, when the checobox is checked, code like #idea.is_private = true gets executed.
To make that works, we have to add the is_private and is_private=(true_or_false) methods in the model.
I have a table: family_children (the model is family_child) where family has many children.
I get the children like this:
#family_children = #family.children
where .children is an association to family_children table.
In a view I want to iterate through the children, and put each of them in a text_field. Of course, I need these fields as params when the page is POSTing. I.e. I think that I should get the children as an array.
How can I achieve that?
I mean, if I'll write
<%= text_field 'child', 'name' %>
I don't really get what I need.
Try something like this in your view:
<% #family_children.each_with_index do |c, i| %>
<%= text_field_tag "children[#{i}]", c.name %>
<br />
<% end %>
This should return params[:children] after posting which should be an array. I wasn't sure of the name of the property you want to show in the text box so I have assumed it is called 'name'.
Actually, #family_children object acts as array, so you can simply call each or map on it.
Do you want to put the children's names in a form field or in the view as just a part of the page text? could you include the view file?
since u want the family_children data to be POSTed, u need to see the concept of nested attributes. please see http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html and http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for
class Family
has_many :children, :class => "FamilyChild"
accepts_nested_attributes_for :children
end
class FamilyChild
belongs_to :family
end
and the form can be as
<%= form_for #family do |p| %>
First name: <%= p.text_field :first_name %>
Last name : <%= p.text_field :last_name %>
<%= fields_for #family.children do |c| %>
<%= c.text_field :child_name %>
<% end %>
<%= f.submit %>
<% end %>