Rails - Nested Forms - Get a attribute from another model - ruby-on-rails

I'm new to Rails so maybe this is a stupid question. I'm struggling to get a attribute from another model in a nested form. Let me explain:
I have 3 models linked each other. Poi -> PoiDescription <- DescriptionType
One Poi can have multiple descriptions and a description have only one description type. I'm creating the PoiDescriptions inside the Poi form with a nested form. Every thing is working well, but now, inside the fields_for I want a label before the textarea with the name of the description type. But I don't know how to get it...I can't do something like 'p.description_type.name' so how can I get that attribute?
Here is my code:
Poi Controller
def new
#poi = Poi.new
#descriptions = DescriptionType.all
#descriptions.each do |d|
#poi.poi_descriptions.new(description_type_id: d.id)
end
end
Poi form
<%= form_with model: #poi do |f| %>
...
<div class="col-md-12">
<%= f.fields_for :poi_descriptions do |p| %>
<%= p.hidden_field :description_type_id %>
<%= p.text_area :description %>
<% end %>
</div>
...
Schema
create_table "description_types", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "poi_descriptions", force: :cascade do |t|
t.text "description"
t.bigint "poi_id"
t.bigint "description_type_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["description_type_id"], name: "index_poi_descriptions_on_description_type_id"
t.index ["poi_id"], name: "index_poi_descriptions_on_poi_id"
end
create_table "pois", id: :serial, force: :cascade do |t|
t.text "name"
t.float "longitude"
t.float "latitude"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "monument_id"
t.integer "beacon_id"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.index ["beacon_id"], name: "index_pois_on_beacon_id"
t.index ["monument_id"], name: "index_pois_on_monument_id"
end
Hope you can help me! Thanks in advance.

To get from the form_builder_object to the actual object you can do p.object.description_type.name
If you just want that as a title and not as an input field you can either:
Add it in a p or span tag and make it look like a label with css or
Add a label_tag with a custom name and title as you need. https://apidock.com/rails/ActionView/Helpers/FormTagHelper/label_tag

Related

Datalist in rails form

A really noob question, but i try with different options and I dont get it.
I Have a form for a new "Cancha" and a field that references to "Mmpp", In the field mmpp_id i need to see a list with the differents kinds of "Mmpp" (already created some options), right now if I put for example "1" i get Mmpp:0x00007f7fb1600378 in the show, Already change the show to <%= #cancha.mmpp.nombre %> and I get exactly what I want in the show, but the problem is in the form I need a list to pick.
Thanks in advance
<%= form.text_field :mmpp_id, class: 'form-control' %>
create_table "canchas", force: :cascade do |t|
t.string "nombre"
t.string "descripcion"
t.integer "capacidad"
t.boolean "operativa"
t.bigint "mmpp_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["mmpp_id"], name: "index_canchas_on_mmpp_id"
create_table "mmpps", force: :cascade do |t|
t.string "nombre"
t.string "descripcion"
t.integer "densidad"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
This will create a dropdown
<%= form.select :mmpp_id, Mmpp.all.map { |r| [r.nombre, r.id] } %>
This was simpler and with the same html classes of the other inputs, form.select work but give some style problems.
<%= f.association :mmpp_id, label_method: :nombre, value_method: :id %>

collect_select, I want to select users only with the admin role as true in my dropdown menu

<div class="field">
<%= form.label :user_id%>
<%= form.collection_select :user_id, User.all, :id , :emailaddress%>
How can I modify the select to only select the email address of users with their admin role as True?
Here is my schema..
create_table "courses", force: :cascade do |t|
t.integer "coursenumber"
t.integer "user_id"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_courses_on_user_id"
create_table "users", force: :cascade do |t|
t.string "firstname"
t.string "lastname"
t.string "title"
t.integer "officenumber"
t.string "emailaddress"
t.integer "phone"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin"
I think you can use the where method, as you would normally:
User.where(admin: true)
<%= form.collection_select :user_id, User.where(admin: true), :id , :emailaddress%>
You also could create a scope in your model named admins, and then just call User.admins or something like that.

RAILS - How do I add a select tag and put all my category items

So I have a scaffold for both blogs and post_category.
I made an association with both of them. Here's my schema:
create_table "blogs", force: :cascade do |t|
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "slug"
t.integer "status", default: 0
t.bigint "post_category_id"
t.index ["post_category_id"], name: "index_blogs_on_post_category_id"
t.index ["slug"], name: "index_blogs_on_slug", unique: true
end
create_table "post_categories", force: :cascade do |t|
t.string "name"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
So simply I created a couple of post categories and when I try to make an association with blog items so whenever I create a new blog I can display a select statement and choose my preferred category for the blog item I am trying to create but I don't know how to display all categories on all forms and on the index.html.erb file:
<div class="field">
<%= form.label :category %>
<%= form.collection_select :post_category, PostCategory.all %>
</div>
How can I achieve this? And make sure that it saves the data as well?
as per this reference, the format is
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
and for your code, it can be like this
<%= form.collection_select(:post_category, :post_category_id, PostCategory.all, :id, :name, prompt: true) %>
update 2:
inside your blog_controllers
# white list parameter
def blog_params
params.require(:blog).permit(
:post_category_id,
... others fields
)
end

has_and_belongs_to_many with join table and checkbox collection

I am trying to make an admin page that has a nested form for another model.
I have a Playbook model:
playbook.rb
has_and_belongs_to_many :groups
accepts_nested_attributes_for :groups
my form view
_form.html.haml
<%= form_with(model: playbook, local: true) do |form| %>
...
<%= collection_check_boxes(:group, :group_ids, Group.all, :id, :name) %>
<div class="actions">
<%= form.submit %>
</div>
To explain it more, playbooks can have many groups which are another model and I want to save to the groups_playbooks join table automatically when saving the playbook using what I think would be a nested form. I just dont know how to do the nested form with a collection of checkboxes like my view.
Here is part of schema to help give a better picture:
create_table "groups", force: :cascade do |t|
t.string "name"
t.string "variables"
t.bigint "server_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["server_id"], name: "index_groups_on_server_id"
end
create_table "groups_playbooks", id: false, force: :cascade do |t|
t.bigint "group_id", null: false
t.bigint "playbook_id", null: false
end
create_table "groups_servers", id: false, force: :cascade do |t|
t.bigint "group_id", null: false
t.bigint "server_id", null: false
end
create_table "playbooks", force: :cascade do |t|
t.string "name"
t.string "play"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "description"
end
create_table "playbooks_servers", id: false, force: :cascade do |t|
t.bigint "playbook_id", null: false
t.bigint "server_id", null: false
end
create_table "servers", force: :cascade do |t|
t.string "name"
t.string "ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "group_id"
t.index ["group_id"], name: "index_servers_on_group_id"
end
According to specification you should use playbook instead of groups
<%= collection_check_boxes(:playbook, :group_ids, Group.all, :id, :name) %>
But as you have the form builder you should look on that specification
For your case
<%= form.collection_check_boxes(:group_ids, Group.all, :id, :name) %>

Questions and Answers Ruby on Rails website

I’m developing question and answers application, where a user attempts to answer questions, I am looking to define a custom method rather than doing coding in the controller methods, creating a separate method that can be called to check the answer the user submitted against the answers database table, where the question_id and the user_input is the same as the Answers database.
Can anyone guide me with where I am going wrong or is there a better approach to checking the user submitted input against the database and then inputting the submission into the database.
Submissions form
<%= form_for :submission :controller => :submissions :action => 'check_answer' do |f| %>
<%= f.text_field :contnet, :value => '' %>
<%= f.submit 'Submit Answer' %>
<% end %>
Submissions_controller
def check_answer
answer = Answer.find_by(question_id: params[:question_id][:content])
if answer.present?
#insert into submissions table, display correct and add to scoreboard
else
redirect_to competitions_path
end
end
Answers Table :
create_table "answers", force: :cascade do |t|
t.string "content"
t.integer "question_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Question_table :
create_table "members_questions", force: :cascade do |t|
t.string "title"
t.integer "category_id"
t.integer "point_id"
t.integer "event_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "file_file_name"
t.string "file_content_type"
t.integer "file_file_size"
t.datetime "file_updated_at"
end

Resources