I currently have categories seeded to my database within a 'category' model, what I'm trying to do is have a dropdown on the new post page which allows me to select what category it belongs to.
The problem is I'm currently getting below:
This is the field I'm currently using within the form.
<div class="field">
<%= f.select :category, Category.all, :prompt => "Select One" %>
</div>
Any help would be fantastic.
Thanks
UPDATE
Offers Controller Create
def create
#offer = Offer.new(offer_params)
respond_to do |format|
if #offer.save
format.html { redirect_to #offer, notice: 'Offer was successfully created.' }
format.json { render :show, status: :created, location: #offer }
else
format.html { render :new }
format.json { render json: #offer.errors, status: :unprocessable_entity }
end
end
end
Try using this:
<%= f.select :category_id, Category.all.collect{|c| [c.name, c.id]}, :prompt => "Select One" %>
More info can be found here.
Don't forget to add :category_id to permitted parameters list for Post in your controller.
Instead of doing Category.all - which gives you back an ActiveRecord Object you have to specify the attribute on the Object you want.
There is a built in form helper for that:
<%= f.collection_select(:category_id, Category.all, :id, :name) %>
Rails guides for form helpers might help: http://guides.rubyonrails.org/form_helpers.html
Related
I am trying to create recurring events using ice_cube and recurring_select gems.
Here is my _form.html.erb code:
<%= simple_form_for(#event) do |f| %>
<div class="form-inputs">
<%= f.select_recurring :day, [IceCube::Rule.daily] %>
<%= f.input :start_time %>
<%= f.input :end_time %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
In my controller I have (among other things):
def new
#event = Event.new
end
def create
#event = Event.new(event_params)
respond_to do |format|
if #event.save
format.html { redirect_to #event, notice: 'Event was successfully created.' }
format.json { render :show, status: :created, location: #event }
else
format.html { render :new }
format.json { render json: #event.errors, status: :unprocessable_entity }
end
end
end
def event_params
params.require(:event).permit(:day, :start_time, :end_time, :reserved)
end
As you can see I want to create the same event for each day in a week, but actually my :day column remains empty if I submit this form.
Can you give some feedback? I don't know what can be wrong
Your escape_params seems to be wrong, it should be event_params as you have used in the update action:
private
def event_params
params.require(:event).permit(:day, :start_time, :end_time, :reserved)
end
Update:
After looking into recurring_select gem, the data that it is sending to the server is something like this:
event[:day]: {"interval":1,"until":null,"count":null,"validations":null,"rule_type":"IceCube::DailyRule"}
So it is not a simple single value parameter that you can store in a single field.
You have two choices here, either serialize this value and store it in a single field or create separate fields for each parameter in the database.
And since your data in day field is a hash, permit function simply won't work on it. You can see more information on Rails issue tracker.
Trying to create a form field where a user can submit a url per: http://apidock.com/rails/v3.2.13/ActionView/Helpers/FormHelper/url_field
I'm getting an error: ActionView::Template::Error (undefined method `homepage' for #
here is the model:
class Idea < ActiveRecord::Base
has_many :comments
mount_uploader :picture, PictureUploader
attr_accessible :description, :name, :picture, :homepage
end
the view in form.html.erb
<%= form_for(#idea) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :link %><br />
<%= url_field("homepage") %><br />
</div>
<div class="actions">
<%= f.submit %>
the view in show.html.erb
<p><b>Name: </b><%= #idea.name %></p>
<p><b>Link:</b><%= #idea.homepage %></p>
ideas_controller
def create
#idea = Idea.new(params[:idea])
respond_to do |format|
if #idea.save
format.html { redirect_to #idea, notice: 'Idea was successfully created.' }
format.json { render json: #idea, status: :created, location: #idea }
else
format.html { render action: "new" }
format.json { render json: #idea.errors, status: :unprocessable_entity }
end
end
end
def show
#idea = Idea.find(params[:id])
#comment = #idea.comments.build
respond_to do |format|
format.html # show.html.erb
format.json { render json: #idea }
end
end
Basically, when you're yielding, and using, a variable to the block in form_for, it already sets the association of the form fields.
ie:
url_field('user', 'homepage')
is equivalent to
f.url_field('homepage')
Check out the url_field, and the form_for documentation
IMHO using url_field in the form builder is antiquated and prone to errors. Eventually I was able to find: rails auto link from tenderlove: https://github.com/tenderlove/rails_autolink coupled with tinymce-rails from spohlenz: https://github.com/spohlenz/tinymce-rails. With these 2 gems you can build a full-featured form field and display the output much more effectively. Hopefully this helps someone else.
I'm using rails 4.0.1
<%= form_for #event, :html => { :multipart => true} do |f| %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="field">
<%= f.label :place_id %><br>
<%= f.collection_select(:place_id, #places, :id, :title) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And I want to check for current_user.id and Place.user_id (it stores creator id). In Events cotroller i'm trying to use:
def create
#places = Place.all
#event = Event.new(event_params)
#event.user_id = current_user.id
#curplace = Place.find_by(id: params[:place_id])
#event.content = #curplace.id
respond_to do |format|
if #event.save
format.html { redirect_to #event, notice: 'Event was successfully created.' }
format.json { render action: 'show', status: :created, location: #event }
else
format.html { render action: 'new' }
format.json { render json: #event.errors, status: :unprocessable_entity }
end
end
end
But i got an error. I think i'm not getting this Place_id param right or anything else?
Further to the comment from Ankush Kataria, the form_for helper basically creates a form which combines all the params into a hash, as opposed to form_tag, which just makes the params independently
As you've discovered, this means your params will be accessed by:
#form_for
params[:variable][:param]
#form_tag
params[:param]
form_for
The reason why this is important is because if you're using the RESTful routes interface, you'll be able to create / edit / update a variety of records
form_for basically keeps consistency throughout this process, pre-populating your forms with the various values, and keeping your code DRY
To call a form_for helper, you have to define the #varaible the form will populate. This #variable needs to be an ActiveRecord object, and is why you have to build it in the new action before your form shows
form_tag
form_tag is much more independent of the form_for helper, doesn't require any #variable, and creates the params individually
You'd use a form_tag for the likes of a contact us form or similar
Your Code
Your form looks good, but your create action can be dried up:
def create
#places = Place.all
#event = Event.new(event_params)
respond_to do |format|
if #event.save
format.html { redirect_to #event, notice: 'Event was successfully created.' }
format.json { render action: 'show', status: :created, location: #event }
else
format.html { render action: 'new' }
format.json { render json: #event.errors, status: :unprocessable_entity }
end
end
end
private
def event_params
params.require(:event).permit(:title, :content).merge(user_id: current_user.id, place_id: params[:event][:place_id])
end
You are right that params[:place_id] isn't returning the value you expect. It only returns nil. To get the :place_id that's submitted by the form, you have to do this:
#curplace = Place.find(params[:event][:place_id])
Just replace the old line with the code above. It's because your form submits the data in the fields inside an :event key in the params hash since you're using the form_for helper method provided by Rails. That is its default behavior unless you change the 'name' attribute's value in the input fields.
Hope that helps!
I have an app where the user can submit a project. For each field they have a choice of either putting in new data into the database, or selecting old data from past projects to fill that field.
I am having trouble getting this to work for this piece of code in my New view:
<%= form_for(#technol) do |tech| %>
<%= fields_for(#project_technol) do |ab| %>
<%= text_field_tag :tech, nil, :maxlength => 30 %>
OR<br />
<%= ab.label "All Tech"%> </br>
<%= collection_select( :technols, :id, Technol.all, :id, :tech, {}, {:multiple => true } ) %>
</div>
<% end %>
<% end %>
At the moment the user can select many technologies from the collection_select, and they get saved with the project, but I am trying to give them the option to put there own technologies in through a text box.
My controller actions:
NEW
def new
#project = Project.new
#technol = Technol.new(params[:tech])
#all_technols = Technol.all
tech_ids = params[:technols][:id].reject(&:blank?) unless params[:technols].nil?
#project_technol = #project.projecttechnols.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #project }
end
end
CREATE
def create
#project = Project.new(params[:project])
params[:technols][:id].each do |tech|
if !tech.empty?
#project.projecttechnols.build(:technol_id => tech)
end
end
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render json: #project, status: :created, location: #project }
else
format.html { render action: "new" }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
So to sum up, I want the user to have the option to enter new tech into the database, AND select existing tech from the dropdown, then all get saved with the project, and the new tech entered get saved in the technol table.
Any ideas? I am a rails noob so please remember this when trying to answer. Any help will be much appreciated. Thanks in advance
How about using token fields instead of a drop down and text field?
Check this revised RailsCast:
http://railscasts.com/episodes/258-token-fields-revised
Here's the original screen cast that's free if you don't have a RailsCast subscription:
http://railscasts.com/episodes/258-token-fields
I will suggest you to use a autocomplete which accepts multiple values. which will improve your view plus the coding will be easy
If I leave the input box blank. I get this error everytime. I don't want it to make new record when it's blank. when not, I want it to make new record.
this input box is nested and the code of controller is written like this to avoid error
def create
# Check if there is any contact info added
if params[:girl][:contact_attributes][:mail].empty?
params[:girl].delete(:contact_attributes)
end
#girl = Girl.new(params[:girl])
respond_to do |format|
if #girl.save
format.html { redirect_to #girl, notice: 'Girl was successfully created.' }
format.json { render json: #girl, status: :created, location: #girl }
else
format.html { render action: "new" }
format.json { render json: #girl.errors, status: :unprocessable_entity }
end
end
end
view is like this
<%= form_for(#girl) do |f| %>
....
<div class="field">
<%= f.label :mail %><br />
<%= f.fields_for :contact_attributes, #girl.contact do |contact| %>
<%= contact.text_field :mail %>
<% end %>
</div>
....
<div class="actions">
<%= f.submit %>
</div>
<% end %>
my model
class Girl < ActiveRecord::Base
has_many :users
has_one :contact
accepts_nested_attributes_for :contact
attr_accessible :id, :name_en, :name_ja, :gender_id, :contact_attributes, :photo, :tag_list
searchable do
text :name_en, :name_ja
text :contact do
contact.mail
end
end
has_attached_file :photo,
:styles => {
:thumb=> "100x100>",
:small => "400x400>" }
acts_as_taggable_on :tags
acts_as_commentable
end
You have to set
#girl = Girl.new
inside your else block, just before
format.html { render action: "new" }
The error happens because you render the new template and inside it the form_for(#girl) gets a nil object - #girl. In order to render the line <%= f.label :mail %><br /> it tries to call the mail method on the given #girl object in order to get its default value. Since the #girl object is nil and not set in the create action before you render the new template you get this error.
UPDATE:
I misunderstood your situation in the answer on the first part of this post. The solution in my opinion is redirecting to the new girl path instead of just rendering the new action. While rendering only renders the view redirecting will make a full-stack request process. Assuming you have the route new_girl_path set you should replace format.html { render action: "new" } with
format.html { redirect_to new_girl_path }
You can run `rake routes and see what named routes you have set.
I problem is the following few lines of code.
if params[:girl][:contact_attributes][:mail].empty?
params[:girl].delete(:contact_attributes)
end
If mail is empty in user contact you have removed the contact attributes and created only the user object.
So if you call #girl.contact you will get nil.
I don't know why you have removed the contact attributes.If you still want to do it you need to add one more line.
if #girl.save
format.html { redirect_to #girl, notice: 'Girl was successfully created.' }
format.json { render json: #girl, status: :created, location: #girl }
else
#Assuming you have the association like: user has_one contact
#user.build_contact
format.html { render action: "new" }
format.json { render json: #girl.errors, status: :unprocessable_entity }
end
And one more thing
<%= f.fields_for :contact_attributes, #girl.contact do |contact| %>
can be simply written as
<%= f.fields_for :contact do |contact| %>
Replace same line of code with <%= form_for( :girl, :url => {:action => :create}) do |f| %>