Rails: How do I just show the current user? - ruby-on-rails

Its a messaging app but it only shows all the users. How do I show the current user?
<%= form_for :conversation, url: :conversations, html: { class: "" } do |f| %>
<div class="modal-body">
<form>
<div class="form-group">
To:
This code works by showing the users name, but when its sent.... it doesn't get saved.
<input type="text" class="form-control" id="recipient-name">
The code bellow is the only one that works but it shows all the users..
<%= f.select(:recipients, User.all.collect {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
</div>
This is the rest of the code.
<div class="form-group">
Subject:
<%= f.text_field :subject, class: "form-control" %>
</div>
<div class="form-group">
Message:
<%= f.text_area :body, class: 'form-control', placeholder: "Type your message here", rows: 4 %>
</div>
Full code:
<%= form_for :conversation, url: :conversations, html: { class: "" } do |f| %>
<div class="modal-body">
<form>
<div class="form-group">
To: <input type="text" class="form-control" id="recipient-name">
<%= f.select(:recipients, User.name {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
</div>
<div class="form-group">
Subject:
<%= f.text_field :subject, class: "form-control" %>
</div>
<div class="form-group">
Message:
<%= f.text_area :body, class: 'form-control', placeholder: "Type your message here", rows: 4 %>
</div>

Assuming you know your current user's id, just change:
<%= f.select(:recipients, User.all.collect {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
To:
<%= f.select(:recipients, User.where(id: current_users_id ).collect {|p| [ p.name, p.id ] }, {}, { multiple: true , class: "chosen-select form-control" })%>
Instead of returning an array of every user, and operating upon that, this will simply return an array of the one user you care about. That said, with a better understanding of your application as a whole, we could definitely find better display options.

Does this work?:
<%= f.collection_select :recipients, User.all.where('name is not ?', nil), :id, :name,
{ prompt: "Choose User..." } %>

Related

Simple_Form Auto Disabling Inputs on Reload

Updating simple_form works fine but when I reload the page, it renders all the inputs as disabled. Any ideas? I can't find anything in the documentation that says what causes it to do this automatically. Thanks
the simple form.
<%= simple_form_for #product_campaign, url: update_completion_criteria_rules_partner_product_product_campaign_path(partner_id: #partner.id, product_id: #product.id, id: #product_campaign.id), remote: true, html: { id: "product-campaign-completion-criteria-rules"} do |f| %>
<div class="">
<%= f.simple_fields_for :completion_criteria_rules, f.object.completion_criteria_rules.order(:created_at) do |complete_criteria_rule| %>
<%= render 'completion_criteria_rule_fields', :f => complete_criteria_rule %>
<% end %>
<%= link_to_add_association "Add Completion Criteria Rule", f, :completion_criteria_rules, class: "btn btn-info float-left mt-10", id: "add-completion-criteria-rule", data: { } %>
<button type="submit" class="btn btn-info float-right mt-10" id="update-product-campaign-form" ><span id="save-journey-button-text">Save Changes</span></button>
</div>
<% end %>
completion_criteria_rule_fields partial
<div class="form-row">
<div class="form-group col-md-6">
<%= f.input :events, collection: CompletionCriteriaRule::EVENTS_OPTIONS, label: 'Choose Events', include_blank: false, input_html: { class: "form-control form-field-type", "data-provide": "selectpicker", multiple: true } %>
</div>
<div class="form-group col-md-6">
<%= f.input :actions, collection: [['Add Campaign', 'add_campaign']], label: 'Choose Action', input_html: { class: "form-control form-field-type actions-dropdown", "data-provide": "selectpicker", multiple: true } %>
</div>
</div>
<div class="form-row add-campaign-dropdown-wrapper" <% unless f.object.actions&.include?('add_campaign') %>style="display:none;<% end %>">
<div class="form-group col-md-6">
<%= f.input :transition_campaign_id, collection: #product_campaign.product.product_campaigns.where.not(id: #product_campaign.id).published.map{|k,v| [k.name.titleize, k.id]}, label: 'Select Campaign To Add', input_html: { class: "form-control form-field-type", "data-provide": "selectpicker" } %>
</div>
<div class="form-group col-md-6">
<label>Campaign Start Delay</label>
<div class="input-group">
<%= f.input_field :transition_campaign_delay, class: "form-control form-field-type" %>
<span class="input-group-addon">days</span>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<span class="float-right">
<%= link_to_remove_association 'Remove Rule', f, class: "btn btn-danger btn-xs" %><br>
</span>
</div>
</div>
<div class="divider"></div>
</div>
completion_criteria_rule.rb
class CompletionCriteriaRule < ApplicationRecord
EVENTS_OPTIONS = [["Appointment Booked", "appointment.booked"], ["Appointment Attended", "appointment.attended"], ["Appointment Cancelled", "appointment.cancelled"], ["Lifecycle Changed to Client", "lifecycle.client"], ["Lifecycle Changed to Lead", "lifecycle.lead"], ["Lifecycle Changed to Former Client", "lifecycle.former_client"], ["Lifecycle Changed to None", "lifecycle.none"]].freeze
belongs_to :product_campaign
belongs_to :transition_campaign, class_name: 'ProductCampaign', foreign_key: 'transition_campaign_id', optional: true
validates :product_campaign, :events, :actions, presence: true
validates :transition_campaign, :transition_campaign_delay, presence: true, if: -> { actions&.include? 'add_campaign' }
before_save :reject_blank_events
before_save :reject_blank_actions
def reject_blank_events
events.reject!(&:blank?)
end
def reject_blank_actions
actions.reject!(&:blank?)
end
end
Found out that I had some js that was disabling form inputs with a certain class that was disabling the inputs after page load. All working now.

Setting the end_time value the same as start_time value in a rails form

Rails 6.0.3
I am using a form to schedule meetings.
It is being used for both single time meetings that span over several days (with start_time and end_time) and tasks that last only one day.
For singular day meetings, I need the end_time to be set to the same value as start_time, without user selecting it.
I have tried many things in the controller, but can't work it out.
How would you go about this.
Thanks for the help
<div class="border border-grey-light rounded" style ="padding: 10px;">
<%= form_with(model: meeting, local: true, :html => {:id => "flatpickr-form-single"} ) do |form| %>
<div class="mb-6">
<%= form.label :name, class: 'label' %>
<%= form.text_field :name, required: true, class: 'form-control', placeholder: "Task name" %>
</div>
<div class="mb-6">
<%= form.label :body %>
<%= form.rich_text_area :body, class: 'form-control' %>
</div>
<div class="start_time_result mb-6" style ="width: 30vw;">
<%= form.label :start_time, class: 'label' %>
<div class="flex items-center justify-between max-w-md">
<%= form.text_field :start_time, data: { behavior: "flatpickr" }, placeholder: "Date and time select ...", class: "form-control" %>
</div>
</div>
<div class=" field" style ="width: 30vw;">
<%= form.label :end_time, class: 'label' %>
<div class="end_time_result flex items-center justify-between max-w-md" >
<%= form.text_field :end_time, data: { behavior: "flatpickr" }, placeholder: "Date and time select ...", class: "form-control required" %>
</div>
</div>
<%= form.submit class: "btn btn-primary text-base py-1.5 px-5", value: "Confirm" %>
<% end %>
</div>
<script>
const selectElement = document.querySelector('.start_time_result');
selectElement.addEventListener('change', (event) => {
const end_time_result = document.querySelector('.end_time_result');
end_time_result.textContent = `${event.target.value}`;
});
</script>
You can add a before_action in the controller and set the end_time parameter value to the same as the start_time from there.

NoMethodError in Discussions#create

Below is code extract from my file Users/JBossman/sites/discussions/app/views/discussions/_form.html.erb where line #20 raised this error undefined method 'map' for nil:NilClass
enter code here
<%= simple_form_for(#discussion) do |f| %>
<%= f.error_notification %>
<div class="field">
<div class="control">
<%= f.input :title, required: true, input_html: { class: 'input' }, wrapper: false, label_html: { class: "label" } %>
</div>
</div>
<div class="field">
<div class="control">
<%= f.input :content, required: true, input_html: { class: 'textarea' }, wrapper: false, label_html: { class: "label" } %>
</div>
</div>
<div class="field">
<label class="label">Channel</label>
<div class="control has-icons-left">
<span class="select">
<%= f.input_field :channel_id, collection:#channels.map { |c| [c.channel, c.id] }, prompt: "Select channel" %>
</span>
<span class="icon is-small is-left">
<i class="fa fa-tag"></i>
</span>
</div>
</div>
<div class="field">
<div class="control">
<%= f.button :submit, class:"button is-info" %>
</div>
</div>
<% end %>
the error is here: #channels.map { |c| [c.channel, c.id] }
your #channels variable is nil.
make sure you set #channels in your create action.
Looks like #channels is nil. Ideally, it should be initialized as [] empty array.
Alternatively, you can also use (#channels || []).map { |c| [c.channel, c.id] } to render empty form.
change #channels.map { |c| [c.channel, c.id] } to below, as #channels is not set(nil).
Assuming that you are having Channel model.
i. If you want to display all the channels in collection, then you can do it as below:
Channel.pluck(:channel, :id)
ii. If you want to display specific channels in collection, then define scope in Channel like favorites
Channel.favorites.pluck(:channel, :id)
I fixed a similar problem with a little change .map to .collect function, you may give it a try..

Rails select - default selected value error

I am trying to set the selected attribute for select but it does not seem to be working
<%= f.fields_for :age_range, OpenStruct.new(#campaign.age_range) do |d| %>
<div class="form-group">
<%= d.label :min, "Age Range", :class => 'col-sm-2 control-label' %>
<div class="col-sm-2">
<%= d.text_field :min, :class => 'form-control' %>
<%= d.select :min, options_for_select(13..90), { include_blank: "Min Age", selected: '23' }, { class: 'form-control'} %>
</div>
<div class="col-sm-2">
<%= d.text_field :max, :class => 'form-control' %>
<%= d.select :max, options_for_select(13..90), { include_blank: "Max Age", selected: '23' }, { class: 'form-control'} %>
</div>
</div>
<div class="line line-dashed b-b line-lg pull-in"></div>
<% end %>
Even by forcing the value i am not able to get it selected
Updated from the Answers
<%= d.select :min, options_for_select((13..90), #campaign.age_range[:min]), { include_blank: "Min Age" }, { class: 'form-control'} %>
But am not able to access the hash value of min to the selected value
#campaign[:age_range] is a hash in the database
You can supply it as a second argument to the helper method options_for_select, for example:
# Static number
options_for_select(13..90, 13)
# or retrieved somehow from form object
options_for_select(13..90, d.object.min)

Rails nested forms , hide remove button for first element

Hi i hava a Rails app that uses nested forms, so for example on a section you can add, as many links as you want.. also i have this other code for citizen as some user have two citizens.
My problem here is that at least you need to enter 1 citizen.. this i can make it with jquery validate, im already running that.. The problem is the Delete button that Rails insert for each field.. So i can literaly delete all fields in the form
Is there a way so just the fields added by user have the delete button.. and not all of them?
Is there any documentation about this.. i cant found it.
Here is my code in view..
<div id="nacionalidad">
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
</div>
The model citizen.rb
class Citizen < ActiveRecord::Base
attr_accessible :country_id
belongs_to :player
end
Thanks
Here is the full view code. Everything is working just 2 issues:
1) The delete button is present always even for first item, need to remove this delete btn for 1st item
2) If i select a country for citizen, it adds a second option, is there a way to avoid this.. and Only add the new field if the user clics on this.. add button..
Thanks!!!
Full View Code
<!-- Información personal y de contacto -->
<div id="wrapper_signup">
<%= link_to image_tag("espanol/logo.jpg", :border => 0), root_path , :class => 'logoo' %>
<div id="loggeddiv">
<%= link_to "#{current_user.email}", '#' %> |
<%= link_to (t ('generales.salir')), destroy_user_session_path, :method => :delete %>
</div>
<div id="navsteps" >
</div>
<div id="signupdiv">
<%= nested_form_for #player, :url => wizard_path do |f| %>
<div id="nombre">
<%= f.label :name %>
<%= f.text_field :name , :value => "#{current_user.name}"%>
</div>
<div id="apellidos">
<%= f.label :lastname %>
<%= f.text_field :lastname, :value => "#{current_user.lastname}" %>
</div>
<div id="cumple">
<%= f.label :birthday %>
<%= f.date_select :birthday, :start_year => 1950, :include_blank => true %>
</div>
<div id="altura">
<%= f.label :height %>
<%= f.select :height, Player::HEIGHT.each {|h| [ h, h ] } , :include_blank => true %> <%= f.select :height_measure, Player::HEIGHT_MEASURE.each {|h| [ h, h ] } %>
<%= f.select :inches, Player::INCH.each {|h| [ h, h ] }, {}, :style => (#player.inches.present? && #player.height_measure == 'pies' ? 'display: inline ' : 'display: none') %>
<%= f.label :inches, :id => 'inch_label', :style => (#player.inches.present? && #player.height_measure == 'pies' ? 'display: inline ' : 'display: none') %>
</div>
<div id="peso">
<%= f.label :weight %>
<%= f.select :weight, Player::WEIGHT.each {|w| [ w, w ] }, :include_blank => true %> <%= f.select :weight_measure, Player::WEIGHT_MEASURE.each {|h| [ h, h ] } %>
</div>
<div id="ciudad">
<%= f.label :city %>
<%= f.text_field :city %>
</div>
<div id="cnatal" >
<%= f.label :birthplace %>
<%= f.text_field :birthplace %>
</div>
<div id="nacionalidad">
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
</div>
<div id="idiomlen">
<%= f.label :languages %>
<% for language in Language.find(:all) %>
<div class="idiomlenbox"><%= check_box_tag "player[language_ids][]", language.id, #player.languages.include?(language) %>
<%= t("languages.#{language.name}") %></div>
<% end %>
<div id="idiomlenotro">
<%= f.label :other_languages %><br>
<%= f.text_field :other_languages %>
</div>
</div>
<div id="cargafoto">
<button type="button" class="photo-button" onclick="document.getElementById('files').click();"><p> <%= t('generales.photo') %> </p></button>
<div id="upload-wrap">
<%= f.file_field :avatar , id: "files" %>
</div>
<div class="thumbperwrap">
<output id="list">
<div class="wraptocenter"><span></span>
<% if #player.avatar.present? %>
<%= image_tag #player.avatar.url(:profile), :class => "thumbper" %>
<% else %>
<img src="../assets/espanol/playersample.png" class="thumbper">
<% end %>
</div>
</output>
</div>
</div>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
document.getElementById('list').innerHTML = "";
var span = document.createElement('span');
span.innerHTML = ['<div class="wraptocenter"><span></span><img class="thumbper" src="', e.target.result,
'" title="', escape(theFile.name), '"/></div>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
<div id="videosyt">
<%= f.fields_for :links do |link| %>
<div id="videosytin">
<%= link.label :url %>
<%= link.text_field :url %>
<%= link.link_to_remove t('generales.delete') %>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :links %>
</div>
<div id="direc">
<%= f.label :cp %>
<%= f.text_field :cp %>
</div>
<div id="telef">
<%= f.label :phone %>
<%= f.text_field :phone %>
</div>
<div id="celu">
<%= f.label :cellphone %>
<%= f.text_field :cellphone %>
</div>
<div id="webpp">
<%= f.label :web_page %>
<%= f.text_field :web_page %>
</div>
<div id="next11">
<%= f.submit t('generales.next'), :class => 'siggreenc' %>
</div>
<% end %>
</div>
</div>
<%= javascript_tag do %>
$('#player_height_measure').on('change', function() {
if (this.value == 'pies') {
$('#player_inches').css('display', 'inline');
$('#inch_label').css('display', 'inline');
} else {
$('#player_inches').css('display', 'none');
$('#inch_label').css('display', 'none');
}
});
<% end %>
<style type="text/css">
#commentForm { width: 500px; }
#commentForm label { width: 250px; }
#commentForm label.error, #commentForm input.submit { margin-left: 253px; }
#signupForm { width: 670px; }
#signupForm label.error {
margin-left: 10px;
width: auto;
display: inline;
}
#newsletter_topics label.error {
display: none;
margin-left: 103px;
}
</style>
<%= javascript_tag do %>
window.onload = function() {
// validate signup form on keyup and submit
$(".edit_player").validate({ // initialize the plugin
errorElement: 'div'});
$("#player_name").rules("add", { required: true, minlength:2, messages: { required: "<%= t('generales.camporequerido') %>", minlength: "Mínimo 2 caracteres"}});
$("#player_lastname").rules("add", { required: true, minlength:2, messages: { required: "<%= t('generales.camporequerido') %>", minlength: "uh minlength?"}});
$("#player_birthday_1i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthday_2i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthday_3i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_height").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_weight").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_city").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthplace").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_citizen").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_phone").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_cellphone").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#files").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
};
jQuery.extend(jQuery.validator.messages, {
required: "<%= t('generales.camporequerido') %>",
remote: "Please fix this field.",
email: "Ingresa un correo electrónico válido.",
url: "Please enter a valid URL.",
date: "Please enter a valid date.",
dateISO: "Please enter a valid date (ISO).",
number: "Please enter a valid number.",
digits: "Please enter only digits.",
creditcard: "Please enter a valid credit card number.",
equalTo: "Please enter the same value again.",
accept: "Please enter a value with a valid extension.",
maxlength: jQuery.validator.format("Please enter no more than {0} characters."),
minlength: jQuery.validator.format("Please enter at least {0} characters."),
rangelength: jQuery.validator.format("Please enter a value between {0} and {1} characters long."),
range: jQuery.validator.format("Please enter a value between {0} and {1}."),
max: jQuery.validator.format("Please enter a value less than or equal to {0}."),
min: jQuery.validator.format("Please enter a value greater than or equal to {0}.")
});
<% end %>
You can use jquery first selector to remove the first delete button based on the id or classname of the parent div (which you aren't currently setting)
<div class="citizens_update">
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
And then use jquery to find the first instance of delerr in the citizens_update div and remove it
$(".citizens_update").find("#delerr:first").remove
http://jsfiddle.net/tiri/ayTrw/

Resources