I am working on a rails 3.2.9 project with a Mongoid back end. I am trying to create posts and if the post is missing a title and content, the model should fail to save which it does properly. When an object is fixed and passes validation, I save it and now create a new post. If I try to save this one with the missing items, the error count just seems to append the previous one even though these are two different objects.
I am using the error_messages helper from dynamic_form to display my errors. Any Ideas?
Here is a sample error message:
152 errors prohibited this post from being saved
There were problems with the following fields:
Title can't be blank
Title can't be blank
Title can't be blank
Title can't be blank
Title can't be blank
The list continues on quite a way. Code is just basic form code:
= form_for #post,:as => :post, :url => post_path(:id=>#post.id), :method => :put do |f|
=f.hidden_field :is_question
#content
.title-page
%h1
New Post
= f.error_messages
In the model I have:
validates_presence_of :title
validates_presence_of :content
and my controller method:
def publish
#post = Post.first(conditions:{_id:params[:post_id]})
#post.assign_attributes(params[:post])
#post.published=true
if #post.save
redirect_to "/"
else
#video = Video.new
render action: "new"
end
end
Related
I have this semantic nested form to destroy a nested object in Active Admin.
= semantic_form_for book.chapters.new, url: {controller: "admin/products", action: :remove_chapter} do |f|
= f.inputs do
li
label Select
= f.collection_select :chapter_product_id, book.chapter_products.order(:name), :id, :name, include_blank: 'Select Chapter'
= f.actions do
= f.action :submit, label: "Remove Chapter"
It works fine, but I feel it is wrong to use a semantic_for_for book.chapters.new since I am not actually creating anything.
I am just making a dropdown select based on a collection to remove an Object.
Just looking to see if there is a better way to do this than how I am doing it now.
I was thinking of just adding a delete button in a table_for, but I can't seem to properly direct to the member_action without getting a route error even though I use the exact same route as the controller in the semantic_form (and added method: :post).
Tried a whole bunch of options from this thread with no success -- https://github.com/activeadmin/activeadmin/issues/53
Thanks!
I just thought of it from a different simpler angle.
I linked to the nested resource's destroy directly, instead of trying to make a member_action in the mother object.
table_for product.chapters do
...
column(:delete) { |c| link_to 'Delete', admin_chapter_path(c), class: 'member_link', method: :delete, 'data-confirm': "Are you sure you want to delete this?" }
end
And since I wanted to be redirected back to the same page I came from I just hacked into the controller method on the nested Object's page and managed my redirects from there.
ActiveAdmin.register Chapter do
actions :index, :show, :destroy
controller do
def destroy
...
redirect_back fallback_location: admin_chapter_path, notice: "Message"
end
end
end
So as it stands I have a form partial which starts off as:
<%= form_for(#merchandise) do |f| %>
It works perfectly for editing the data that I have already assigned in the rails console. When I try to use it for a "new" form that creates new merchandise (in this case the singular form of merchandise, I don't have nested resources, multiple models etc.), I get a no Method error that states
"undefined method 'merchandises_path' for #<#<Class:0x64eaef0>:0x95d2370>".
When I explicitly state the URL in the form_for method:
<%= form_for(#merchandise url:new_merchandise_path) do |f| %>
I get it to open and I finally have access to the form, however in this case I get a routing error that states
"No route matches [POST] "merchandise/new"".
I decided to write out that route in my routes file which previously just had:
root "merchandise#index" resources :merchandise
After I add the route it literally does nothing. I click submit and it takes me to the form but there is no new data in the database. I am at a complete loss and have been at this for hours googling and stack overflowing and I just don't know what to do anymore. All help is seriously appreciated. I'm adding a pastebin with all my code in the following url:
http://pastebin.com/HDJdTMDt
I have two options for you to fix it:
Option 1:
Please try to do this for best practice in Rails:
routes.rb
change your routes use plural
resources :merchandises
merchandises_controller.rb
Rename your file controller and class into MerchandisesController
class MerchandisesController < ApplicationController
def index
#merchandise = Merchandise.all
end
def new
#merchandise = Merchandise.new
end
def create
#merchandise = Merchandise.new(merchandise_params)
if #merchandise.save
redirect_to merchandises_path
else
render :new
end
end
def show
#merchandise = Merchandise.find(params[:id])
end
def edit
#merchandise = Merchandise.find(params[:id])
end
def update
#merchandise = Merchandise.find(params[:id])
if #merchandise.update(merchandise_params)
redirect_to #merchandise, notice: "The movie was updated"
else
render :edit
end
end
def merchandise_params
params.require(:merchandise).permit(:shipper, :cosignee, :country_arrival_date, :warehouse_arrival_date, :carrier, :tracking_number, :pieces, :palets, :width, :height, :length, :weight, :description, :cargo_location, :tally_number, :customs_ref_number, :released_date, :updated_by, :country_shipped_to, :country_shipped_from)
end
end
Option 2:
If you want to not change many code
/merchandise/_form.html.erb
in partial file
/merchandise/new.html.erb
<%= render 'form', url: merchandise_path, method: 'post' %>
/merchandise/edit.html.erb
<%= render 'form', url: category_path(#merchendise.id), method: 'put' %>
First Rails question! Loving it so far. :D
I know this has been asked multiple times but none of the answers worked for me. When a signup fails, I'd like to go back to the old form and retain the old form values. I know I'm suppose to render the same view on failed attempt but for some reason it doesn't work.
Here's my form in the signup view
<%= form_for(#new_user, :url => {:action => 'attempt_signup'}) do |f| %>
//form fields like :name, :email, :password
<% end %>
Controller
def signup
#new_user = User.new
#some code to populate form fields.
end
def attempt_signup
#user = User.new(params[:user])
if #user.save
redirect_to(:controller => 'static', :action => 'index') #this works
else
render :action => 'signup' #this doesn't
end
end
This works well, if there are no validation errors and user successfully signs up but I get the error if signup fails due to some validation error.
I think I understand the problem which is that on rendering signup again after a failed attempt, none of the controller code in the signup action runs again, since I'm just rendering. Because of this, #new_user isn't defined. But I don't know how to solve this. If signup fails due to validation error, instead of going back to the old form, I get the error First argument in form cannot contain nil or be empty. So how do I solve this and retain the filled values as well?
Also, I don't understand how just rendering the view back would repopulate the form fields with the previous values.
Thanks!
change it to
def attempt_signup
#new_user = User.new(params[:user])
if #new_user.save
....
.....
I am following the Rails guide for doing multi-model nested form. I have 2 models, Page and Picture. Page has_many Pictures. I'm putting the Picture file field within the Edit Page form using fields_for.
Each time I upload an image, the form will add an additional file field to allow for a new Picture to be uploaded.
The behavior I want is for the Page form to only always have one file field which will create a new Picture. I don't need previous pictures to be editable.
The questions thus are 1) how can I do the above? 2) should I even be using nested form? Because I'm not editing other parts of the Page when creating a picture.
You can just use:
#routes.rb
resources pages do
resources pictures
end
#PicturesController.new
#picture = Picture.new
#views/pictures/new.haml
= form_for #picture
#form code here
Or you can place form wherever you want and send it to pictures controller:
#views/pages/show.haml
= form_for [#page, Picture.new] do |f|
= f.hidden_field :page_id, :value => #page.id
= f.file_field :file #change to your own
= f.button :submit
#PicturesController
def create
#picture = Picture.new(params[:picture])
if #picture.save
redirect_to :back, :notice => "success"
else
#some code
end
end
How can I render after executing an action in a restful controller instead of redirecting.
I have a controller with standard actions, and I added a special action that adds data to the resource in question, via a form on the #show page (Think comments on a post). I am validating the input from the form and want to re-render the show action on error and redirect to the show action on success.
I want to render to save the user from inputting their info twice, but when I try to render the show action with an error in the flash[:notice] I get an error saying that I am not specifying an ID. When I do specify an ID, it tries to render a new template that doesn't exist yet.
I am thinking that it should be a as simple as:
def add_comment
if my_validation?
save the object
redirect_to :action => "show", :id => params[:id]
else
render :action => "show", :id => params[:id]
end
end
This is not my actual code, just something I put together just now as an example.
The best way is to re-render the :new
def create
#obj = TheObject.new(params[:object])
render :action => :new unless #obj.save
end
And in the new.html.erb
<% form_for :obj,
:url => object_url(#obj), :html => {:method => :post} do |f| %>
<%= f.text_field :name %>
<% end %>
That way, the inputs in the form will be pre-filled with what the user entered.
Create a new data object and add the values from the form, before you rerender, think it would work then. If you still get problems, try setting a boolean for editing new vs. existing rows, or create two different views entirely.
I've done it before but I don't quite remember how. Sometimes when I used the very typical use of the MVC pattern, it was allmost "automagical", othertimes (as I had to use an old quirky database) I had to code all the magic myself; sometimes usin the .new? function (or what it was called) on the ActiveRecord object, othertimes I used temporary "magic values" for ID (typically alphabetic strings for invalid id values.
(I appologize if I made some mistakes, it's a while since I coded Rails code...)