changing form behavior on submit based on radio button selection - ruby-on-rails

I'm using Rails 3.1.0.rc5. I want to have a form with a pair of radio buttons, enable and disable, and a field to enter an integer (expire_after_days, the number of days until ticket expiration), with a hidden field for the fixed parameter subdomain_name. I'd like to be able to use the same simple form to create, edit, or delete a record, depending on which radio button is checked.
So if enable is checked, with no record found for the subdomain_name, a record would be created on form submission.
If enable is checked, and a record is found, the existing record should be updated on form submission.
And if disable is checked, the record should be deleted on form submission.
Is this a reasonable thing to do? If so, what tips do you have for how to do it?

It's not ideal nor restful to have all 3 actions (create, update, destroy) cramped up in just one controller method, but if you wish to continue on this dirty route here's what you could do:
def my_dirty_method
if params[:enable].present?
if params[:subdomain_name].present?
# Edit subdomain
else
# Create subdomain
end
end
if params[:disable].present?
# Delete subdomain
end

Related

Captcha with Multipart Form Rails

I have a multipart form that I need a captcha for at the end. Essentially, a user is allowed to create/update a draft but not submit it for admin review until everything is done. There is a captcha meant for the last submission but the problem is that when I add it to the form, I can't use any of the other submit buttons because the captcha isn't filled out. Is there any way around this?
I'm using simple_captcha and Rails 3.2.
Thanks!
I haven't used simple_captcha before, but seems like you are doing #object.save_with_captcha in every case. You have multiple options to solve this, but one i came up with is:
In the controller, verify if all the fields (mandatory only i guess) are filled, and if they are, then save your object using #object.save_with_captcha, otherwise do the usual #object.save which wont trigger the captcha validation. Something like this:
def create
#object = MyObject.new(params[:my_object])
if #object.has_mandatory_fields_filled?
#object.save_with_captcha
else
#object.save
end
end
In the has_mandatory_fields_filled? method you would check that all the mandatory fields of your form are not empty/nil etc.

Allowing users to choose between a public and private profile. Better way to display this in view?

I am making it so users can choose to allow their profiles to be public or only allowed to registered users.
Here are the steps that I took:
rails g migration AddIs_publicToUsers is_public:boolean
rake db:migrate
I have the :is_public to default=> true in my db
Then I added this into the user.rb model
attr_accessible :is_public
Now I'm trying to create the view but would it be better to do this using radioboxes instead of a checkbox?
<%= f.label :is_public, "Set Profile as Private" %>
<%= f.check_box :is_public, :checked => false %>
The problem with above is that after users check their profile as private and they come back to the page, it doesn't stay checked which means that users aren't able to make their profile public again.
Finally, how do I ensure that is_public is referring to non-signed in users vs. sign-in users? For example, if is_public is true, then all people including signed in and non-signed in can view the profile. However, if is_public is false, then only signed in users of the website can view.
Your question is really multiple questions in one.
Radio vs Checkbox
Given that this appears to be a mandatory and binary choice with a default value, radio buttons are going to be your best bet. As a tip, make sure that your labels are set correctly so the user can click on the label and doesn't have to find the radio button itself with their mouse (which is tiny).
Radio buttons not updating
If the radio buttons are not updating after the form is submitting, the user's input is getting lost somewhere. Check the params being submitted to see if the controller is receiving them, then make sure they are translated into the saved record. If the record is being updated, make sure your radio buttons are reflecting the database value in the form itself.
Signed-in users vs. non-signed-in users
My recommendation is to create a before_filter on the profiles controller, which checks the value of is_public, checks whether the user is signed in, then redirects non-authenticated users wherever you like.

Ruby on rails form validation for user profiles advice needed

I have one model that holds validation rules for my edit_profiles page. On the edit profile page I'm using jquery accordion to split user edit_profile into different sections for users to edit information. Each section is a separate form.
e.g.
Basic info (form 1)
Personal Stats (form 2)
Favourite things (form 3)
About me (form 4)
My problem is successfully filling out information on one form and clicking update is unsuccessful because other validation rules that have been set are firing in because other forms are failing validation because they have not yet be filled in.
I've tried to use the validation_group gem but this seems to have no affect.
I'd like to know if there is an easy way to do this?
Can't I just bunch up validation rules for each form and put them in separate methods and only make them come into play when the update button from a matching form has been clicked?
So if the update button on form 1 is clicked the form_one_validations method would be fire for example and the unrelated validation methods won't.
I would really really appreciate an example of how to do this.
This is the action responsible for y edit_profile view:
def edit_profile
#profile = Profile.find_by_user_id(current_user.id)
end
It is based inside my profiles controller.
Kind regards
I ended up using :allow_blank
This way the fields don't have to be filled in but all other important validation rules are still enforced if they need to be.
I can propose you such approach: you can add additional fields to your model, something like "basic_info_completed" which will be set up once after user has filled all corresponding information. And make all necessary validations conditional and perform them only when such field is set to true. So before user fills all fields of profile section, they are all can be edited without validation, but after profile fields are completed, validation is turned on for that part of profile.

How to trigger different actions based on submit button in rails

I have a form with a list of stuff, and an action already in place to update items.
I want to have another button, which when clicked triggers a different action to remove the selected items.
= form_for #new_item,:url => {:controller => "item_lists",:action => "update_list" } do |f|
- #items.each do |it|
%input{:type=>"hidden",:name=>"item_list[#{it.id}]position",:value=>it.position, :class=>'position'}
%textarea{:name=>"item_list[#{it.id}]field1"}
=it.field1
%textarea{:name=>"item_list[#{it.id}]field2"}
=it.field2
%input{:type=>'checkbox', :name=>'selected_items[]', :value=>it.id}
=(it.valid?) ? "" : it.errors.full_messages
%input{:type=>"submit", :value=>"Save changes", :name=>'save'}
%input{:type=>"submit", :value=>"Remove selected", :name=>'delete'}
This question seems to indicate I should inspect params in my action to figure out what was clicked. But that feels messy, my controller could quickly degenerate into a mass of ifs when I add more actions.
Is there a more elegant way to do this, i.e. get it to just route to the correct method?
Thanks for any help...
This doesn't really gel with REST. In REST and Rails you're typically going to have one action per endpoint, not decide on the endpoint based on some criteria in the request.
That being said, you can filter actions based on the submit button by checking the name of the button pressed. See this SO question.
I'd argue though that this is only appropriate if your form is doing slightly different things, like perhaps a submit button that updates in place versus a submit button that redirects somewhere afterward, e.g. "Update" versus "Update and Continue" (contrived, but you get what I mean).
Addressing your concern in the comments, your method wouldn't have to devolve into a long sequence of ifs. You could just write some code to determine which method to call based on the name of the submit button. A simple implementation might be:
# your form action
def update_list
send update_list_action
end
protected
def update_list_action
# just return the first action name found in the params
action = %w(save delete).detect {|action| params[action] }
"update_list_#{action}"
end
def update_list_save
# handle save
end
def update_list_delete
# handle delete
end
I would suggest you to add a dropdown menue with the option "delete", "update",... and add some jQuery code that observes the selected item and changes the action of your form depending on the value because you shouldnt use one action to update and delete objects! There should be one action for updating and one for deleting!

Best way to create preview functionality in Rails

I'm looking to implement preview functionality in my posts scaffold. All I need to do is allow a user to enter information in the new view (/posts/new) and then replace the submit button with a preview button.
Once the preview button is clicked, the user is routed to the preview page (probably /posts/new/preview). If the user wants to make a change they would click 'go back' or if they are happy with the post they can then submit the post.
I found this article (http://eyedeal.team88.org/node/105) but it seems dated. Any ideas on what the best approach for this would be?
Many thanks,
Tony
On submit from create page, in the new action, build the object but do not save it to the database. Then render the object in its show view with a flag set in the new action to display a submit button. In your show view, always have a form with all the attributes of the object to be saved to db in hidden input fields or in display:none's. When the flag is set, you show the submit button. On submit, you go to the new_to_db action which saves the object to the db.
The link you have posted is a way, but I prefer to save object and set a boolean flag, let's say public to false (:default => false defined in migration).
Then what you basically do is actually create the post and redirect to show action, where you have
edit button (render edit action),
post button (custom action to set public flag to true)
and cancel button (which actually deletes the post)
and maybe continue later button, which keeps the post and redirects to any other page, so the user can come back later and finish editing it.
When you need to show all posts, define a named_scope :visible, :conditions => ['posts.public = ?', true] and call Post.visible instead of Post.all in index and similar actions. You could also define a default_scope with conditions ['posts.public = ?', false], but bare in mind that if you want to find posts that are not visible, you will have to use #without_scope.
This way is better than the one in your link, because user can always come back later and finish editing the post and the publish it. However you will store more objects in DB and have to deal with invisible posts (don't show them by default, etc.)

Resources