Update Devise user with association to 'Language' model - ruby-on-rails

Building a Rails app using devise. The user can edit all the information on their profile page (name, description etc.) inside devise/edit.html.erb. The user model has an association to language model. I want the user to be able to pick their own language when editing their profile from a f.select. How do I make this happen?
Thanks in advance.
Edit.html.erb:
<div class="panel-body">
<div class="panel-body">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div>
<div class="form-group">
<%= f.label :coach_id %>
<%= f.select(:coach_id, User.where('is_coach = ?', true).pluck(:name, :id), {}, { :class => 'select2 form-control' }) %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.text_area :description, class: 'form-control', rows: '5' %>
</div>
<div class="form-group">
<%= f.label :facebook %>
<%= f.text_field :facebook, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :twitter %>
<%= f.text_field :twitter, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :image %>
<%= f.file_field :image, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :header_image %>
<%= f.file_field :header_image, class: 'form-control' %>
</div>
</div>
<br>
<%= f.submit 'Update Settings', class: 'btn btn-success' %>
<% end %>
</div>
</div>
Schema:
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin", default: false
t.boolean "is_coach", default: false
t.text "description"
t.string "image_uid"
t.string "header_image_uid"
t.string "facebook"
t.string "twitter"
t.boolean "featured"
t.integer "coach_id"
t.string "name"
t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
end
create_table "languages", force: :cascade do |t|
t.string "language_code"
t.integer "user_id"
t.index ["user_id"], name: "index_languages_on_user_id", using: :btree
end
create_table "languages_users", force: :cascade do |t|
t.integer "user_id"
t.integer "language_id"
t.index ["language_id"], name: "index_languages_users_on_language_id", using: :btree
t.index ["user_id"], name: "index_languages_users_on_user_id", using: :btree
end
User
has_and_belongs_to_many :languages
Language
has_and_belongs_to_many :users

Related

Rails- Checkbox not turning true

I've added a checkbox to my Rails project. When the user marks tradeablestatus while creating a book, it should write true, but it is happening false regardless.
books/_form.html.erb
<%= form_with(model: book, local: true) do |form| %>
<% if book.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(book.errors.count, "error") %> prohibited this book from being saved:</h2>
<ul>
<% book.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p> If you want your book to be available, tick the status and if you want your book to be tradeable, tick the tradeablestatus. </p>
<div class="field">
<%= form.label :title %>
<%= form.text_field :title %>
</div>
<div class="field">
<%= form.label :author %>
<%= form.text_field :author %>
</div>
<div class="field">
<%= form.label :pagecount %>
<%= form.number_field :pagecount %>
</div>
<div class="field">
<%= form.label :status %>
<%= form.check_box :status %>
</div>
<div class="field">
<%= form.label :tradeablestatus %>
<%= form.check_box :tradeablestatus %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
tradeablestatus migration (I added the tradeablestatus later as a migration. But I don't know if I should add this to book migration)
class AddTradeableStatusToBooks < ActiveRecord::Migration[6.0]
def change
add_column :books, :tradeablestatus, :boolean
end
end
schema.rb (I suspect it is caused by default: false, null: false)
ActiveRecord::Schema.define(version: 2020_10_28_092816) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "books", force: :cascade do |t|
t.string "title"
t.string "author"
t.integer "pagecount"
t.boolean "status"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "user_id"
t.string "username"
t.boolean "tradeablestatus", default: false, null: false
end
create_table "comments", force: :cascade do |t|
t.string "title"
t.string "content"
t.bigint "user_id", null: false
t.bigint "book_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.boolean "status", default: false, null: false
t.index ["book_id"], name: "index_comments_on_book_id"
t.index ["user_id"], name: "index_comments_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "username"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
add_foreign_key "comments", "books"
add_foreign_key "comments", "users"
end
Hello) 👋 If u want to receive "true" or "false" on your back-end side u should check this first https://apidock.com/rails/ActionView/Helpers/FormHelper/check_box.
There are smth like check_box("puppy", "gooddog", {}, "yes", "no").
Yes and no means that if checkbox are checked then yes value goes to back-end side otherwise no goes to back-end side. U should replace this values with yours)
If problem will not go then post your controller code please)

show user's first_name with devise

How to show user's first_name in page like "Hello, current_user.first_name", my schema
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "first_name", default: "", null: false
t.string "last_name", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
when i tried to do in my page <span>Hello, <%= current_user.email %></span> it's all ok, but whet i tried <span>Hello, <%= current_user.first_name %></span> it's show nothing. Where is my mistake?
The problem here is in your schema, you have t.string "first_name", default: "", null: false which saves the empty string in your database, if you don't pass the first_name.I'm quite sure you are not saving the first_name value to user anyhow and it is by default set to "". When you try to access <span> <%= "Hello, #{current_user.first_name}" %></span> here it return empty string.Here user is present as if user is not present then it would have given error as first_name for nil:NilClass.
add this to your ApplicationController
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
permit_attrs(%i[first_name last_name])
end
def permit_attrs(attrs)
%i[sign_up account_update].each do |action|
devise_parameter_sanitizer.permit(action, keys: attrs)
end
end
in your new.html.erb you have two first name field change one as below:
<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name, autofocus: false, class: "form-control" %>
</div>
to
<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name, autofocus: false, class: "form-control" %>
</div>
So if you are seeking to display user information, this is how I handle that.
Display User Input Fields
<p> Hello <%= #user.first_name %>
Now, if you want to be able to show user input information IF they have it.
If User Filled Out Form
<% if #user.first_name? %>
<p>Hello, <%= #user.first_name %></p>
<% else %>
<p>Hello Anonymous User</p>
<% end %>

Rails: add relationship with other table for Devise user

I want to add an input to my Devise user sign_up form in order to add a team name. I created a specific table for Teams and I created a relationship: Users belong to Team. Team has many users.
The problem is I need to add a Team_id when submiting the sign_up form. How can I save the value of the Team input in the register form to the Team table and get the Id in order to save it to the team_id entry in Devise User table?
My Sign Up form:
<div class="container_index">
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.label :team %><br />
<%= f.text_field :team %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
My user schema:
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.integer "team_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["team_id"], name: "index_users_on_team_id"
end
My application controller:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
skip_before_action :verify_authenticity_token
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:name, :email, :password, :team) }
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:name, :email, :password, :current_password, :team) }
end
Thank you.

Values of helper collection_select is being called twice

I have model Category:
class Category < ActiveRecord::Base
has_many :projects
end
Model project:
class Project < ActiveRecord::Base
belongs_to :category
validates :title, :description, :category, :skill, :payment, presence: true
validates :price, numericality: { only_integer: true }
PRICE_CATEGORIES = ['cat_price1', 'cat_price2', 'cat_price3', 'cat_price4']
end
projects/new
<%= form_for #project, url: {action: 'create'} do |f| %>
<p>
<%= f.label 'Titel' %>
<%= f.text_field :title %>
</p>
<P>
<%= f.label 'Budget' %>
<%= f.text_field :price %>
für
<%= f.select :price_category, Project::PRICE_CATEGORIES %>
</P>
<p>
<%= f.label 'Beschreibung' %>
<%= f.text_area :description %>
</p>
<p>
<%= f.label 'Kategorie' %>
<%= f.collection_select :category_id, Category.all, :id, :name %>
</p>
<P>
<%= f.submit 'erstellen' %>
</P>
<% end %>
schema.rb:
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "projects", force: :cascade do |t|
t.string "title"
t.text "description"
t.integer "price"
t.string "skill"
t.string "location"
t.string "payment"
t.boolean "anonymity"
t.string "file"
t.integer "category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "price_category"
end
When calling <%= f.collection_select :category_id, Category.all, :id, :name %>
all items in dropdown list displaying twice. Cant undestand, why.
For example:
cat1
cat2
cat3
cat1
cat2
cat3
Thank for you help.

How to add multiple images in rails site

I am trying to add several images to my site and am not quite sure how the routing works.
Here is my index.html.erb page
<%= render 'pages/home' unless user_signed_in? %>
<div id="properties" class="transitions-enabled">
<% #properties.each do |property| %>
<div class="box panel panel-default">
<%= link_to image_tag(property.image.url(:medium)), property_path(property) %>
<div class="panel-body">
<%= property.description %><br>
<strong><%= property.user.name if property.user %></strong>
<!-- <% if property.user == current_user %>
<div class="actions">
<%= link_to 'Edit', edit_property_path(property) %>
<%= link_to 'Destroy', property, method: :delete, data: { confirm: 'Are you sure?' } %>
</div> -->
<% end %>
</div>
</div>
<% end %>
</div>
And I think it's after this line <%= link_to image_tag(property.image.url(:medium)), property_path(property) %> that I want to add another image.
Here is my _formfield.html.erb file where I ask for two images
<div class="form-group">
<%= f.label :image %><br>
<%= f.file_field :image, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :street_image %><br>
<%= f.file_field :street_image, class: "form-control" %>
</div>
How do I show the :streetimage properly?
And this is my property model:
class Property < ActiveRecord::Base
belongs_to :user
has_attached_file :image, :styles => { :medium => "300x300", :thumb => "100x100"}
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png"]
validates :image, presence: true
validates :description, presence: true
end
And here's my schema
ActiveRecord::Schema.define(version: 20150429054455) do
create_table "properties", force: :cascade do |t|
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "name"
t.string "street"
t.integer "zip"
t.string "state"
t.string "company"
t.string "city"
t.integer "price"
t.integer "space"
t.string "street_image_file_name"
t.string "street_image_content_type"
t.integer "street_image_file_size"
t.datetime "street_image_updated_at"
end
add_index "properties", ["user_id"], name: "index_properties_on_user_id"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "name"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
It's working now. Looks like I had the wrong variable set and didn't run rake db:migrate before

Resources