Using checkboxes to pass multiple strings to array in migration with ruby - ruby

Im looking to have a user create a post where they specify what instruments they play. There should be a checkbox for each instrument so the user can select the ones that apply to the post. I was able to display the instruments and their checkboxes in the post creation but I cannot figure out how to save them to the post. I get error ActiveRecord::AssociationTypeMismatch.
Displaying all instruments and passing integers for each (Id like to pass strings)
<% Instrument.all.each do |instrument| %>
<%= check_box_tag "post[instruments][]", instrument.id %>
<%= instrument.name %> <br>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
Migration to receive array of integers
class AddTagsToPost < ActiveRecord::Migration[5.2]
def change
add_column :posts, :instruments, :integer, array: true, :default => []
end
end
schema.rb
create_table "instruments", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", force: :cascade do |t|
t.bigint "category_id"
t.string "title"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "account_id"
t.integer "instruments", default: [], array: true
t.index ["account_id"], name: "index_posts_on_account_id"
t.index ["category_id"], name: "index_posts_on_category_id"
end
post.rb model
class Post < ApplicationRecord
belongs_to :category
belongs_to :account
has_many :instruments
validates :title, presence: true, length: { minimum: 3 }
validates :content, presence: true, length: { maximum: 500 }
end
instrument.rb model
class Instrument < ApplicationRecord
belongs_to :posts, optional: true
end
Private end of the posts_controller.rb
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Only allow a list of trusted parameters through.
def post_params
params.fetch(:post, {}).permit(:title, :content, :category_id, instruments:[])
end
end

Related

has_many :through rails

I want to get user1 to accept requests from other users to join user1s post as contributors and be listed out if user1 accepts them
Can't seem to get it to work - Here's my setup:
has_many :through
I'm thinking:
post model
class Post < ActiveRecord::Base
#Join table associations
has_many :group_requests, class_name: "Group",
foreign_key: "requester_id",
dependent: :destroy
has_many :group_users, class_name: "Group",
foreign_key: "accepted_id",
dependent: :destroy
has_many :requester, through: :group_requests
has_many :accepted, through: :group_users
def request(other_post)
group_requests.create(accepted_id: other_post.id)
end
# Unfollows a user.
def unrequest(other_post)
group_requests.find_by(accepted_id: other_post.id).destroy
end
# Returns true if the current user is following the other user.
def accepted?(other_post)
requesting.include?(other_post)
end
user model
class User < ActiveRecord::Base
#Join table associations
belongs_to :group
group model
class Group < ActiveRecord::Base
belongs_to :requester, class_name: "Post"
belongs_to :accepted, class_name: "Post"
validates :requester_id, presence: true
validates :accepted_id, presence: true
end
CreatePosts Migration
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :content
t.timestamps null: false
end
end
end
DeviseCreateUsers Migration
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.integer :post_id
t.string :email, null: false, default: ""
AddUserIdToPosts
class AddUserIdToPosts < ActiveRecord::Migration
def change
add_column :posts, :user_id, :integer
add_index :posts, :user_id
end
end
CreateGroup Migration
class CreateGroups < ActiveRecord::Migration
def change
create_table :groups do |t|
t.integer :requester_id
t.integer :accepted_id
t.timestamps null: false
end
add_index :groups, :requester_id
add_index :groups, :accepted_id
add_index :groups, [:requester_id, :accepted_id], unique: true
end
end
Post Controller
def accepted
#title = "Accepted"
#post = Post.find(params[:id])
#users = #user.accepted.paginate(page: params[:page])
render 'show_accepted'
end
def requester
#title = "Requesters"
#post = Post.find(params[:id])
#users = #user.requester.paginate(page: params[:page])
render 'show_requester'
end
private
def post_params
params.require(:post).permit(:title, :content, :image)
end
Post Show
<% #post ||= current_user(#post) %>
<div class="stats">
<a href="<%= accepted_post_path(#post) %>">
<strong id="following" class="stat">
<%= #post.accepted.count %>
</strong>
following
</a>
<a href="<%= requester_post_path(#post) %>">
<strong id="followers" class="stat">
<%= #post.requester.count %>
</strong>
followers
</a>
</div>
Any suggestions?
You could try this ---
as i think p is your post and you want to get all user_ids.
p.group_members.map{|gm|gm.user_id} #list of all ids in array
### OR try this
p.users #list of all users in array
#if you want to collect ids then
p.users.collect(&:id)
I think it should be helpful for you

Multi model sign up with clearance in Rails 4

So I want to create a Company while signing up as a new user to my application. I use https://github.com/thoughtbot/clearance for authentication.
I have these 2 migrations:
class CreateCompanies < ActiveRecord::Migration
def change
create_table :companies do |t|
t.string :name, null: false
t.string :email, null: false
t.attachment :logo
t.timestamps null: false
end
end
end
And
class CreateClearanceUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email, null: false
t.string :encrypted_password, limit: 128, null: false
t.string :confirmation_token, limit: 128
t.string :remember_token, limit: 128, null: false
t.string :first_name
t.string :last_name
t.attachment :avatar
t.integer :company_id
t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :remember_token
end
end
My models look like this:
class User < ActiveRecord::Base
include Clearance::User
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :users
accepts_nested_attributes_for :users
end
This is my altered Clearance controller:
class Clearance::UsersController < ApplicationController
before_filter :redirect_signed_in_users, only: [:create, :new]
skip_before_filter :require_login, only: [:create, :new]
skip_before_filter :authorize, only: [:create, :new]
def new
#user = User.new
#user.build_company
render template: "users/new"
end
def create
#user = User.new(user_params)
if #user.save
sign_in #user
redirect_back_or url_after_create
else
render template: "users/new"
end
end
private
def avoid_sign_in
warn "[DEPRECATION] Clearance's `avoid_sign_in` before_filter is " +
"deprecated. Use `redirect_signed_in_users` instead. " +
"Be sure to update any instances of `skip_before_filter :avoid_sign_in`" +
" or `skip_before_action :avoid_sign_in` as well"
redirect_signed_in_users
end
def redirect_signed_in_users
if signed_in?
redirect_to Clearance.configuration.redirect_url
end
end
def url_after_create
Clearance.configuration.redirect_url
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, companies_attributes: [:id, :name])
end
end
And at last my form:
<div class="form-item">
<%= form.label :first_name %>
<%= form.text_field :first_name, type: "text" %>
</div>
<div class="form-item">
<%= form.label :last_name %>
<%= form.text_field :last_name, type: "text" %>
</div>
<div class="form-item">
<%= form.label :email %>
<%= form.text_field :email, type: "email" %>
</div>
<div class="form-item">
<%= form.fields_for :companies do |builder| %>
<label>Company</label>
<%= builder.text_field :name, type: "text" %>
<%end%>
</div>
<div class="form-item">
<%= form.label :password %>
<%= form.password_field :password %>
</div>
I can perfectly submit my form, but my company_id is nil when finding the user object in rails console.
Anyone have an idea what I am doing wrong?
Thanks in advance!
You need to use the singular:
= form.fields_for :company
and in your controller:
company_attributes # instead of companies_attributes
and you have one thing in the wrong model! You want to save a company with the user so you need to move accepts_nested_attributes_for to user.rb
accepts_nested_attributes_for :company

Rails Associations - user_id states nil Rails 4

I am completely unsure where i am going wrong and it surprises me that i can not figure it out, so any advise would be much appreciated.
i have 2 models userr(recruiters) & feedbackr(recruiters feedback)
[userr model] userr has_many :feedbackr
[feedbackr model] belongs_to :userr
[schema] i have added userr_id column to the table feedbackrs
[feedbackrs_controller] i have added :userr_id to the feedbackr_params
the problem is, when i create a feedback comment as a recruiter & go
into my console and type Feebackr.find(4) (the last created
feedback) the userr_id shows nil - it
is suppose to display the id of the userr(recruiter) that created a
feedback - i am unsure why it is displaying nil as my associations all seem right -
any advise would be much appreciated - i have my files below -
console
2.1.2 :055 > ap Feedbackr.find(4)
Feedbackr Load (0.3ms) SELECT "feedbackrs".* FROM "feedbackrs" WHERE "feedbackrs"."id" = ? LIMIT 1 [["id", 4]]
#<Feedbackr:0x007fd89136e018> {
:id => 4,
:email => "richill#gmail.com",
:created_at => Sun, 28 Jun 2015 00:29:52 UTC +00:00,
:updated_at => Sun, 28 Jun 2015 00:29:52 UTC +00:00,
:category_feedbackr_id => 6,
:content => "feedback1",
:userr_id => nil
}
=> nil
2.1.2 :056 >
schema
ActiveRecord::Schema.define(version: 20150627235330) do
create_table "feedbackrs", force: true do |t|
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "category_feedbackr_id"
t.text "content"
t.integer "userr_id"
end
create_table "userrs", force: true 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 "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
end
add_index "userrs", ["confirmation_token"], name: "index_userrs_on_confirmation_token", unique: true
add_index "userrs", ["email"], name: "index_userrs_on_email", unique: true
add_index "userrs", ["reset_password_token"], name: "index_userrs_on_reset_password_token", unique: true
end
feedbackr.rb
class Feedbackr < ActiveRecord::Base
belongs_to :userr
end
userr.rb
class Userr < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :feedbackrs
end
feedbackr_controller.rb
class FeedbackrsController < ApplicationController
respond_to :html, :xml, :json
before_action :set_feedbackr, only: [:show, :edit, :update, :destroy]
def index
#feedbackrs = Feedbackr.all.order("created_at DESC")
respond_with(#feedbackrs)
end
def show
respond_with(#feedbackr)
end
def new
#feedbackr = Feedbackr.new
respond_with(#feedbackr)
end
def edit
end
def create
#feedbackr = Feedbackr.new(feedbackr_params)
respond_to do |format|
if #feedbackr.save
format.html { redirect_to dashboard_path, :notice => 'Thank you for your feedback' }
format.xml { render :xml => #feedbackr, :status => :created, :location => [#feedbackr] }
else
format.html { render :action => "new" }
format.xml { render :xml => #feedbackr.errors, :status => :unprocessable_entity }
end
end
end
def update
...
end
def destroy
...
end
private
def set_feedbackr
#feedbackr = Feedbackr.find(params[:id])
end
def feedbackr_params
params.require(:feedbackr).permit(:email, :category_feedbackr_id, :content, :userr_id)
end
end
views/feedbackrs/_form.html.erb
<%= simple_form_for(#feedbackr) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input_field :email, label: 'email address', value: current_userr.email %>
<%= f.association :category_feedbackr, as: :radio_buttons, label: 'How likely are you to recommend us?' %>
<%= f.input :content, label: 'What is the primary reason for your score?'%>
</div>
<div class="form-actions">
<%= f.button :submit, 'Provide Feedback' %>
</div>
<% end %>
<div><%= render 'shared/footer' %></div>
Did you want to set the current_user as the userr ?
def create
#feedbackr = Feedbackr.new(feedbackr_params)
#feedbackr.userr = current_user # And make sure the user is authenticated (though you probably did that in your ApplicationController ?)
respond_to do |format|
if #feedbackr.save
format.html { redirect_to dashboard_path, :notice => 'Thank you for your feedback' }
format.xml { render :xml => #feedbackr, :status => :created, :location => [#feedbackr] }
else
format.html { render :action => "new" }
format.xml { render :xml => #feedbackr.errors, :status => :unprocessable_entity }
end
end
end
Assigning #feedbackr.userr = current_user in your feedbackrs_controller.rb file would automatically generate the user_id field. Since currently, you didn't assign anything to user_id when feebackr is being generated, therefore your userr_id = nil.

How to list the users who LIKE a given Post

I am having trouble figuring out how to list all of the USERS who have LIKED a particular POST. Currently I am using:
<span class="count"><%= dailypost.likes.count %></span>
This has allowed me to count all of the LIKES associated with that particular POST.BUT it does not list the actual users.
I have tried using this to list all of the USERS who LIKED that POST
<%= dailypost.likes %>
Instead I get back:
[#<Like id: 360, dailypost_id: 306, user_id: 1, created_at: "2013-04-28 21:51:45", updated_at: "2013-04-28 21:51:45">,
#<Like id: 319, dailypost_id: 306, user_id: 104, created_at: "2013-04-28 19:27:35", updated_at: "2013-04-28 19:27:35">,
#<Like id: 314, dailypost_id: 306, user_id: 103, created_at: "2013-04-28 19:24:19", updated_at: "2013-04-28 19:24:19">]
DOES ANYONE KNOW HOW I CAN PULL THE LIST OF USERS OR USER_ID'S??
New to RAILS please help!!
MODELS
class User < ActiveRecord::Base
has_many :likes, dependent: :destroy
has_many :dailyposts, dependent: :destroy
end
class Dailypost < ActiveRecord::Base
belongs_to :user
has_many :likes
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :dailypost
end
DATABASE
ActiveRecord::Schema.define(:version => 20130210095553) do
create_table "dailyposts", :force => true do |t|
t.string "content"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "likes", :force => true do |t|
t.integer "dailypost_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
VIEWS
<span class="count"><%= dailypost.likes.count %></span>
<%= dailypost.likes %>
<span class="like">
<% if like = current_user.likes.find_by_dailypost_id(dailypost.id) %>
<%= form_for like, :html => { :method => :delete }, remote: true do |f| %>
<span title="Unlike!"><%= image_submit_tag "Superman1.png" %></span>
<% end %>
<% else %>
<%= form_for current_user.likes.build, remote: true do |f| %>
<div><%= f.hidden_field :dailypost_id, value: dailypost.id %></div>
<%= f.hidden_field :user_id %>
<span title="Like!"><%= image_submit_tag "Superman2.png" %></span>
<% end %>
<% end %>
</span>
The simplest way to understand is to take each like, and ask it for its user:
dailypost.likes.map {|l| l.user}
Of course that does a database lookup for each like, which you may wish to avoid if you have hundreds and hundreds of users.
So a more sophisticated way is to do a single query to get all the users by user_id:
User.find(dailypost.likes.map {|l| l.user_id})
This will give you a list of users, and it's up to you what you do with it. If you just want a HTML list, try this instead:
<ul>
<% dailypost.likes.each do |l| %>
<li> <%= link_to(l.user.name, l.user) %></li>
<% end %>
</ul>
This looks at each like in turn, and then asks it for its user, and then asks the user for its name.

Undefined Method in Picture Controller

Warning, I'm a newb and trying to learn RoR on my own. Been doing the tutorials etc and now trying to learn through experience. Long story short I'm trying to attach a user picture from a url defined by them, with a default pic if they don't supply one. Been running into all kinds of errors, I think I have it down to one primary issue now after hours of trying to figure it all out (since I'm new at this). So right now the error I'm getting is:
NoMethodError in GravsController#update
undefined method `update_attributes' for nil:NilClass
I know this means I need to do something like:
#something = Model.new/build(params[:method])
But I don't know where to define it in my controller (I'm guessing the gravs_controller right?) So here's my code, tear it apart and see if you can help me get this image function working, please :)
class GravsController < ApplicationController
before_filter :signed_in_user
gravs_controller
def create
#graver = current_user.gravs.new(params[:content])
#grav_bool = false
if #graver.save
#grav_bool = true
#grav_bool.save
flash[:success] = "User Picture Saved!"
redirect_to faq_path
else
#grav_bool = false
#grav_bool.save
redirect_to faq_path
end
end
def update
if #graver.update_attributes(params[:content])
#grav_bool = true
#grav_bool.save
flash[:success] = "User Picture Saved!"
redirect_to faq_path
else
#grav_bool = false
#grav_bool.save
redirect_to faq_path
end
end
end
users_controller
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update, :destroy, :gravs]
before_filter :correct_user, only: [:edit, :update, :gravs]
before_filter :admin_user, only: :destroy
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to Inception!"
redirect_to gravs_path
else
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(params[:user])
sign_in #user
flash[:success] = "Profile updated"
redirect_to gravsid_path
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_path
end
private
def correct_user
#user = User.find(params[:id])
redirect_to (root_path), error: "Cannot edit others information!" unless current_user?(#user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
create.html.erb (Inside /views/gravs/)
<% provide(:title, "Edit Picture") %>
<div class="barney">
<div class="trouble">
<h1>Update Your Picture</h1>
<%= gravs_display #graver %>
<%= form_for(:grav) do |f| %>
<div class="field">
<%= f.text_field :content, placeholder: "Enter Picture URL" %>
</div>
<%= f.submit "Update User Image", class: "btn btn-small btn-primary" %>
<% end %>
</div>
</div>
update.html.erb (inside /views/gravs/)
<% provide(:title, "Edit Picture") %>
<div class="barney">
<div class="trouble">
<div class="row">
<div class="span6 offset3">
<h1>Update Your Picture</h1>
<%= gravs_display #graver %>
<%= form_for(:gravs) do |f| %>
<div class="field">
<%= f.text_field :content, placeholder: "Update Picture URL" %>
</div>
<%= f.submit "Update User Image", class: "btn btn-small btn-primary" %>
<% end %>
</div>
</div>
</div>
</div>
** datenumber_create_gravs.rb**
class CreateGravs < ActiveRecord::Migration
def change
create_table :gravs do |t|
t.string :content
t.integer :user_id
end
end
end
schema.rb
ActiveRecord::Schema.define(:version => 20130407202835) do
create_table "gravs", :force => true do |t|
t.string "content"
t.integer "user_id"
end
create_table "microposts", :force => true do |t|
t.string "content"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "microposts", ["user_id", "created_at"], :name => "index_microposts_on_user_id_and_created_at"
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "password_digest"
t.string "remember_token"
t.boolean "admin", :default => false
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["remember_token"], :name => "index_users_on_remember_token"
end
routes.rb
MydeaSample::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :microposts, only: [:create, :destroy]
root to: "static_pages#home"
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/message', to: 'static_pages#message'
match '/faq', to: 'static_pages#faq'
match '/gravs', to: 'gravs#create'
match '/gravsid', to: 'gravs#update'

Resources