Simple form hidden association - ruby-on-rails

This is weird behavior.
I have this as part of a form:
<%= f.association :blog, collection: current_user.blogs, selected: #blog %>
This works. However, as soon as I add this extra attribute:
<%= f.association :blog, collection: current_user.blogs, selected: #blog, as: :hidden %>
I get a validation error saying that my model needs a blog to be associated with it. It seems that adding as: :hidden to it makes it lose the value.
Any ideas?

It does not need to be select, because it's hidden field. I think the following code will solve the problem:
<%= f.input :blog_id, as: :hidden, input_html: { value: #blog.id } %>

Related

Selected drop down menu in simple_form when f.association is present in the view

Can you please tell me if there is a way using simple_form with Rails, when you have "f.associations" present in a view, to disable the selected drop down menu in the form but still use the prefilled value of the field?
I have tried with option ":disabled => true" but it disables the whole text field and a I need a value to be present here. When I submit the form I receive an error that a value should be present.
I have tried with option ":as => :hidden", the input value does not appear, but when I submit the form I receive an error that a value should be present.
I have tried with option ":readonly => true", but drop down menu still appears. It appears grayed out but can still be selected.
Thank you,
Silviu
Use input hidden with same variable and value for f.assocation disabled, when submit form, the needing value will be sended at once time.
Sample code illustrate the case, note line f.association :company get the value company_id but not send, so the f.input :company_id will replace, and works!
Welcome to project railstrace !
<p>Simple Form content: </p>
<%= simple_form_for #user, url: save_path, :method => :post do |f| %>
<%= f.input :email %>
<%= f.association :company, disabled: true %>
<%= f.input :company_id, :as => :hidden, :input_html => {:value => #user.company_id} %>
<%= f.association :roles %>
<%= f.button :submit %>
<% end %>

Translating form_for syntax to simple_form syntax

I have this code within my rails form:
Categories: <%= f.collection_select :tag_ids, Tag.order(:name), :id, :name, {}, {multiple: true} %>
This code is working, but I want to use simpleform gem to redesign my form. However, I cannot seem to figure how to 'translate' this code into simple form. Anyone have any idea how? Thanks.
Something like this should do the trick:
If you have a many to many relation you could first try what the default does.
<%= f.association :tags %>
If the defaults don't work out you can make an explicit collection:
<%= f.input :tag_ids, as: :select, collection: Tag.order(:name), label_method: :name, input_html: {multiple: true} %>
# or
<%= f.input :tag_ids, as: :select, collection: Tag.order(:name).pluck(:name, :id), input_html: {multiple: true} %>
Alternatively if you define the Tag#to_label method you don't have to pass the name of the label method. The Tag#id gets used as default value method. If you would like another value specify the method like so: value_method: :something_else.
See the simple_form Usage section (intro, collections and associations).

rails + simpleform: selected does not set to be enum's value

I have a enum definition for my User model.
class User < ActiveRecord::Base
enum program_of_study: [
:program_of_study_unknown, :program_of_study_cs, :program_of_study_ceg,
:program_of_study_is, :program_of_study_science,
:program_of_study_engineering, :program_of_study_fass,
:program_of_study_business, :program_of_study_others
]
end
And in simple_form I have:
<%= simple_form_for(locals[:user], wrapper: :horizontal_form, html: {class: 'form-horizontal'},
url: {action: (locals[:is_new] ? 'create' : 'update')}) do |f| %>
<%= f.error_notification %>
<%= f.input :program_of_study, collection: User.program_of_studies, include_blank: false, selected: locals[:user].program_of_study %>
<%= f.button :submit, class: 'btn-success' %>
<% end %>
However, it seems that although the program_of_study of a user is 'program_of_study_science'(by checking in rails console), when I render the form, the shown select element still has 'program_of_study_unknown' as the displayed one. The correct one was not selected.
Instead of the enum I used the keys and it seems to work, have you tried that:
collection: User.program_of_studies.keys
I didn't have to specify a selected option. My code looks like this:
input :status, as: :select, collection: Venue.statuses.keys, include_blank: false
My solution in the end
<%= f.input :program_of_study, collection: User.program_of_studies, include_blank: false, selected: User.program_of_studies[locals[:user].program_of_study] %>

Hover over display related text for simple form association field

I am using Rails and simple form. I have a collection that I am displaying with an association field. For each item in the collection, I want to display a hover over title of an attribute belonging to that item, namely description.
Here is my association:
<%= f.association :user_roles, collection: #roles, as: :check_boxes, label_method: :name, label: false %>
I want to display a hover over text of the description of each role. In my head something like the following should be doable:
<%= f.association :user_roles, collection: #roles, wrapper_html: {title: UserRole.where(id: this_current_items_id).first.description}, as: :check_boxes, label_method: :name, label: false %>
or:
<%= f.association :user_roles, collection: #roles, wrapper_html: {title: :description}, as: :check_boxes, label_method: :name, label: false %>
Neither of these work obviously but in my head a solution like this should be easy. I guess the guys at simple form never thought of this situation.
However, is this possible to do? Or, how can I get the ID of the current item so that I am displaying that items description on hover over?
PS: What I need is a simple form hover_method!
You can easily add other attributes to each item in your collection like so:
<%= f.association :user_roles, collection: #roles.map { |r| [r.name, r.id, { title: r.description, "data-toggle": "hover" }] }, as: :check_boxes, label: false %>

undefined method `name' for ["Yes", true]:Array

I acctual don't know where Array ["Yes",true] came from. I have two models like this:
GeneralExam has_many topic_questions
TopicQuestion belongs to general_exam, belongs_to topic
In TopicQuestion, I have columns: general_exam_id, topic_id, number_question, to store a number question for each topic in general exam.
I built a nested form for create new general exam, on form I built a dynamic select, when user choose a course from a dropdown list, I have other dropdown lists to display topics of course chosen by user.
This is my javascript code for dynamic select:
<% content_for :head do %>
<script type="text/javascript">
$(document).ready(function() {
$('#general_exam_course_id').change(function () {
$.ajax({
type: "POST",
url: "<%= update_topics_general_exams_path %>",
data: { course_id: $('#general_exam_course_id').val() },
dataType: "script"
});
});
</script>
<% end %>
#general_exam_course_id is ID of dropdown list for select course. update_topics_general_exams_path is route to my update action in general exam controller, this is my update action:
def update_topics
#course = Course.find(params[:course_id])
#topics = #course.topics
end
I have a update_topics.js.erb also:
$('div#topic_questions select').html("<%= j options_from_collection_for_select(#topics, 'id', 'name') %>");
Dropdown lists in div#topic_questions will get #topics value from update_topics action (I think so) and display it. When I create new general exam, it's ok. But when I press Edit link, it show me an error which I don't know why and where it comes:
NoMethodError in General_exams#edit
undefined method `name' for ["Yes", true]:Array
Extracted source (around line #3):
1: <div class="row">
2: <div class="span6"><%= remove_child_link "Remove below topic", f %></div><br><br>
3: <div class="span3"><%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %></div>
4: <%= f.input :number_question, placeholder: 'Number of questions', label: false, style: 'display: inline' %>
5: </div>
My edit action only have: #general_exam = GeneralExam.find(params[:id]). I don't know why topic association field of general exam display an Array ["Yes", true]. I don't have it, don't define it any where, why it come when I edit general exam?
Update
If I remove label_method: :name, value_method: :id in:
<%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>
The page is not error, but Dropdown lists have value Yes, No in select, not the name of topic I have created for exam. Form can get the number question of each topic, but it can not get name of topic.
When I create:
When I edit:
I found this in config/locales/simple_form.en.yml:
en:
simple_form:
"yes": 'Yes'
"no": 'No'
Is this a problem?
Update: Don't pass #topics in new action but it's still have on new page When course even is not selected yet
My new action:
def new
#general_exam = GeneralExam.new
5.times { #general_exam.topic_questions.build }
##topics = Topic.all
end
As in my extract source above, I have below code in new, edit too (use same form):
<%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>
So I don't pass #topics, but when I go to new page, dropdown lists for topic still display Yes, No value.
Ok , our time for comments chat-like is over :)(the System suggested to move to the chat room ) . The solution it seems to be passing the collection inline in the association of the simple_form :
<%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>
becomes :
<%= f.association :topic, collection: Topic.limit(1), prompt: "Choose a topic", label: false %>
It would work for now , I think .
You've got the right idea by assigning your query to #topics and passing it to your view... but, you're putting it in the wrong actions and not passing them to the right views:
def update_topics
#course = Course.find(params[:course_id])
#topics = #course.topics
end
-
What you should do:
There is NO update view for your update action, so, you must place the following 2 lines:
#course = Course.find(params[:course_id])
#topics = #course.topics
in both your new action and your edit action
Then you can go ahead and use your original simple_form code, which IS/WAS ORIGINALLY correct:
<%= f.association :topic, collection: #topics,
label_method: :name, value_method: :id,
prompt: "Choose a topic", label: false
%>
Alternatively, you could SKIP the #topics in your controllers and simply put the following in your views:
new view
<%= f.association :topic, collection: Topics.all,
label_method: :name, value_method: :id,
prompt: "Choose a topic", label: false
%>
edit view
<%= f.association :topic, collection: Course.find(params[:course_id]).topics,
label_method: :name, value_method: :id,
prompt: "Choose a topic", label: false
%>
NOTE the difference:
I would think that in your new view you would want the user to see ALL possible topics.
While in your edit view you just want them to see the topics for this course, correct?
-
Why it happened:
Since, you were not passing ANY collection earlier, there was no 'name' method/column for simple_form to use as the labels/display values in the dropdown and thus the error message you got regarding Array ["Yes",true]
If/when you removed the label_method: :name, value_method: :id, options you probably would have seen as many choices as you had expected rows in the dropdown, but instead of a list of the course topic names you would have seen a list of Topic objects (something like this):
#<Topic::xxxx>
#<Topic::xxxx>
...
#<Topic::xxxx>
And, when you don't supply the collection, you get only 2 yes/no values which is the simple_form default per the config file you found (config/locales/simple_form.en.yml).
So, as you might have guessed by now, this is why what you finally used...
<%= f.association :topic, collection:
Topic.limit(1),
prompt: "Choose a topic",
label: false
%>
...kind of "worked" as a workaround -- because it *did* execute a proper query and supplied it to the simple_form, but it limited the results to only the *first* topic in the table (without any ordering/sort)
At least, this is what I have learned/gone through. HTH!

Resources