validation on simple form in ruby on rails - ruby-on-rails

I have a simple_form which is not tied to an object. I am using parameters such that whenever i submit a form, it gives parameters to create method in posts controller. Same as form_for_tag.
<%= simple_form_for :postFoo, url: {controller: 'posts', action: 'create', user_id: "#{current_user.id}", group_id: "#{#group.id}" } do |f| %>
<div style="float:left"> <%= f.input :bulletin_post, label: false, placeholder: 'Create new post ...' %> </div>
<div style="float:left"> <%= f.submit "Post", class: "btn btn-warning btn-sm" , id: "bulletinSubmit" %> </div>
<%end%>
Post Controller, create method:
#post = Post.create(user_id: params[:user_id], bulletin_post: params[:postFoo][:bulletin_post], group_id: params[:group_id])
My question is, how to validate the :bulletin_post input field to be non-empty before submitting ? This would be simple if it was directly tied to an object using model validation.

Related

Passing text field value to Rails Controller

I'm fairly new to Rails and I'm stuck with passing a text field value to Rails Controller method. Any help is appreciated, below is my code..
View code:
Upon click of the below button I want to be able to send the username to the Controller method..
<%= link_to "My button", admin_user_creds_path(user_config),
method: :test_user, role: "button" %>
The username is entered in a text field:
<%= form_for [:admin, user_config] do |f| %>
<td class="js-editable-text rf-table__td rf-table__col--username">
<div class="preview js-preview show"><%= user_config.username %></div>
<div class="js-input hide"><%= f.text_field :username, class: "form-control" %></div>
</td>
My routes file:
post "/user_configurations/:id", to: "user_configurations#test_user", as: "user_creds"
My controller:
def test_user
username = user_params[:username]
end
def user_params
params.require(:user_configurations).permit(:username)
end
Instead of using link_to helper you need add a submit button to your form.
<%= form_for [:admin, user_config] do |f| %>
<td class="js-editable-text rf-table__td rf-table__col--username">
<div class="preview js-preview show"><%= user_config.username %></div>
<div class="js-input hide"><%= f.text_field :username, class: "form-control" %></div>
<%= f.submit "My button" %>
</td>
Also please note that method option in link_to helper is either get or post HTTP methods but not the controller action

Rails 4.2 use form_tag to create search but without using query string params

EDIT 2
Related question here.
EDIT
This is the route I need to submit to:
get '/s/:term', controller: :products, action: :search, as: :search_products
I have a search form like this:
<%= form_tag(search_products_path, :method => "get", id: "search-form", name: "f1", enforce_utf8: false) do %>
<div class="input-group">
<%= text_field_tag :search, params[:search], placeholder: "Search products", class: "form-control", name: "search" %>
<div class="input-group-btn">
<button class="btn btn-secondary">
<span class="glyphicon glyphicon-search"></span>
</button>
</div>
</div>
<% end %>
But this creates the url like this:
domain/s?search=[user input]
I need the URL to be like this instead:
domain/s/[user_input]
Yes I do know this is not following Rails convention. I couldn't care less at this point, I just need to figure it out.
Thanks.
There's no way to do this using just form_tag, since the url that the form submits to needs to be dynamic. But it can be done using javascript:
$("#search-form").submit(function(evt) {
var term = $("#search-form input[name='search']").val();
$(this).attr('action', '/s/' + encodeURIComponent(term));
});
This will result in the form submitting to: domain/s/[user input]?search=[user input]
You could further prevent the ?search= parameter from being included in the url by omitting the name attribute from the field (see https://stackoverflow.com/a/3008071/157943), though then you'd need to give it an id or some other way for the javascript snippet above to locate it.
Thanks to the comments from #TarynEast and the other question linked in my second edit, I realised I was very confused - so thank you Taryn!
This has to be done in 2 separate actions/routes, like this:
post '/s', controller: :products, action: :search, as: :search_products
get '/s/:search', controller: :products, action: :index, as: search_results_path
Whatever the user inputs is then posted by the form to that search action.
Here is the form:
<%= form_tag(search_products_path, :method => "post", id: "search-form", name: "f1", enforce_utf8: false) do %>
<div class="input-group">
<%= text_field_tag :search, params[:search], placeholder: "Search products", class: "form-control", name: "search" %>
<div class="input-group-btn">
<button class="btn btn-secondary">
<span class="glyphicon glyphicon-search"></span>
</button>
</div>
</div>
<% end %>
The products#search action simply does a redirect:
def search
# ORIGINALLY: redirect_to "/s/#{params[:search]}"
redirect_to search_results_path(params[:search])
end
Then we can extract the :search param and use it to search the model, like so:
def index
if params[:search] && !params[:search].blank?
#products = Product.search params[:search]
...
etc

Rails form_for sending params to controller action and not model

In the controller review_queue I have a custom action that posts a result to a target URL, I want to build a form for this action. I am not going to save any of the fields to the DB I am just going to pass them in the params to the post_review action.
def post_review
RestClient::Request.execute(:method => :post,
:url => Rails.application.secrets['target_url'],
:content_type => :json,
:payload => #result_params.merge!(params[:reasons]).to_json,
:headers => HEADERS)
end
In the view I have a form that will be filled out and on submit it should send up the reasons when the form is submited, I am setting the review_queue_id and the status in the form, since these are static, but the reasons should come from the textarea
<%= form_for(:review_queue, url: { action: 'post_review', :review_queue_id => #review_queue.id, :status => 'accepted'} ) do |f| %>
<div class='form-group'>
<label for='comment'>Please give a reason? (required)</label>
<%= f.text_area(:reasons, placeholder: 'Your commentns ...', rows: 9, class: 'form-control') %>
</div>
<div class='modal-footer'>
<%= f.submit 'Approve', class: 'btn btn-success btn-decission btn-modal-left-side' %>
<button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
</div>
<% end %>
error message:
NoMethodError - undefined method `reasons' for #<ReviewQueueApplication:0x007fa7ff7832d8>:
It seems as if rails is assuming the MVC architecture here, and assuming I want to pass the reasons to the review_queue model. there is no reasons column so it's dropping a no method error. Is there a way of specifying that the form is 'temporary' and only getting as far as the controller?
This seems like it should be a simple thing but there is some rails magic happening here.
NoMethodError - undefined method `reasons' for
ReviewQueueApplication:0x007fa7ff7832d8
form_for assumes that you are creating a form for a model object and expects the fields to be present in that specific model's table(in a normal situation).
You should be going with form_tag
<%= form_tag post_review_path, method: :get, :review_queue_id => #review_queue.id, :status => 'accepted'} ) do |f| %>
<div class='form-group'>
<label for='comment'>Please give a reason? (required)</label>
<%= text_area_tag(:reasons, placeholder: 'Your commentns ...', rows: 9, class: 'form-control') %>
</div>
<div class='modal-footer'>
<%= submit_tag 'Approve', class: 'btn btn-success btn-decission btn-modal-left-side' %>
<button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
</div>
<% end %>
And in the controller access it like params[:reasons]. Also if you noticed, I've added method: :get to the form_tag as you don't want to save the info to DB
The rails helper form_for is used for forms for rails resources. You want to use the form_tag helper. Search for form_for and form_tag here for more information on these 2 methods.

How to pass parameters from html.erb to a different html.erb

I'm playing with the messenger gem in rails 4.
I have a graph of nodes and I want to be able to bring up a message box (initially in a different page but will make it a partial later) when a node is pressed so that the current user can message that node.
The id for the clicked node is kept in a div called NameID
At the moment all I've got working is a button that opens the new message page and then you can choose a user from a drop down list. I guess I want that drop down list- the recipient- to be prepopulated from the currently clicked node on the index page.
Here is what I have so far:
index.html.erb
<p><a class="btn btn-lg btn-primary" id="BtnMessageNode" href="/messages/new">Start conversation</a></p>
<div id=NameID><<THIS IS POPULATED BY JAVASCRIPT>></div>
messages_controller.rb
class MessagesController < ApplicationController
before_action :authenticate_user!
def new
#chosen_recipient = User.find_by(id: params[:to].to_i) if params[:to]
end
def create
recipients = User.where(id: params['recipients'])
conversation = current_user.send_message(recipients, params[:message][:body], params[:message][:subject]).conversation
flash[:success] = "Message has been sent!"
redirect_to conversation_path(conversation)
end
end
helpers/messages_helper.rb
module MessagesHelper
def recipients_options(chosen_recipient = nil)
s = ''
User.all.each do |user|
s << "<option value='#{user.id}' data-img-src='#{gravatar_image_url(user.email, size: 50)}' #{'selected' if user == chosen_recipient}>#{user.name}</option>"
end
s.html_safe
end
end
messages/new.html.erb
<% page_header "Start Conversation" %>
<%= form_tag messages_path, method: :post do %>
<div class="form-group">
<%= label_tag 'message[subject]', 'Subject' %>
<%= text_field_tag 'message[subject]', nil, class: 'form-control', required: true %>
</div>
<div class="form-group">
<%= label_tag 'message[body]', 'Message' %>
<%= text_area_tag 'message[body]', nil, cols: 3, class: 'form-control', required: true %>
</div>
<div class="form-group">
<%= label_tag 'recipients', 'Choose recipients' %>
<%= select_tag 'recipients', recipients_options(#chosen_recipient), multiple: true, class: 'form-control chosen-it' %>
</div>
<%= submit_tag 'Send', class: 'btn btn-primary' %>
<% end %>
There are basically two ways to pass parameters to GET routes:
A. Named segments
/users/:user_id/message/new
This nested route would be great if you are sending a message to a single user.
B. Query parameters
Rails supports query parameters as well:
/message/new?to=2
Rails automatically adds query parameters to the params hash. So in this case you would do params[:to].
You can use the Rails route helpers so that you don't have to deal with encoding urls yourself:
new_message_path(to: #user.id)
Use query params for optional parameters like filters and sorting or in this case a preset. Don't use them like users?id=5.

Generate hidden form field data with rails button_to helper?

Currently, i use the following code for passing params[:id] to line_items create
<%= button_to 'Add to Cart', { controller: 'line_items', action: 'create', id: brick }, class: 'green radius nice button', method: :post, remote: true %>
However, it will append the id param on url query which i didn't suppose button_to to do. What i want is passing the id param via hidden the form field. Can i do that in button_to or any workaround for this issue?
Starting with Rails 4.1.0, button_to has now the additional options :params which can receive a hash that will be transformed into hidden fields. For example:
button_to 'Send Invitation', invitation_path(user), params: {'user[email]' => user.email}
Will give :
<form action="/users/invitation" class="button_to" method="post">
<div>
<input type="submit" value="Resend">
<input name="user[email]" type="hidden" value="user#yahoo.com">
</div>
</form>
I have done something similar in a module of my project:
First, I added a form with a hidden field:
<%= form_tag({:action => 'my_action'}, :id=>"item_form", :method => :post, :remote=>true) do%>
<%= hidden_field_tag :item_id, 0%>
<% end %>
all mi items on the list will have a check_box_tag wich contains the item id:
<%= check_box_tag "item_ids", item.id, false,:id => item.id, :class => "my_fancy_class"%>
when an item is picked just catch the event, replace the value on the hidden_field and trigger the form:
function( event, ui ) {
$("#item_id").attr('value',ui.selected.id);
$('form#item_form').submit();
}
if you want to render stuff just add a action.js.erb file to your controller view folder, but thats another thing.

Resources