This is my simple web app for following user, it has an error, please help me :)
I can't insert following_id into database. I'm stuck with it
*This is my application_controller
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include WelcomeHelper
end
*WelcomeHelper
module WelcomeHelper
def login(user)
session[:user_id] = user.id
end
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
*relation_controller
class RelationController < ApplicationController
def create
follow = User.find(params[:relation][:following_id])
current_user.following << follow
redirect_to current_user
end
*welcome_controller
class WelcomeController < ApplicationController
def index
end
def create
user = User.find_by_username(params[:session][:username])
if user
login user
redirect_to user
else
render 'index'
end
end
def sucess
#users = User.all
#relation = Relation.new
end
end
*relation model
class Relation < ActiveRecord::Base
attr_accessible :follower_id, :following_id
belongs_to :follower, :class_name => "User"
belongs_to :following, :class_name => "User"
end
*usermodel
class User < ActiveRecord::Base
attr_accessible :pass, :username
# Who am I following?
has_many :relations, :foreign_key => :follower_id
has_many :following, :through => :relations
# Who am I followed by?
has_many :relations, :class_name => "Relation", :foreign_key => :following_id
has_many :followers, :through => :relations
validates :username, :pass, :presence => true
validates :username, :pass, :length => { :minimum => 4 }
validates :username, :uniqueness => true
*relations table
class CreateRelations < ActiveRecord::Migration
def change
create_table :relations do |t|
t.references :follower
t.references :following
t.timestamps
end
add_index :relations, :follower_id
add_index :relations, :following_id
end
end
*routes
get "welcome/sucess"
get "welcome/error"
root :to => "welcome#index"
get '/users/:id', :to => 'welcome#sucess', :as => "user"
match '/relations', to: 'relation#create', via: 'post'
resources :users
resources :posts
resources :relations
post 'login' => 'welcome#create'
*sucess view
Following
<ul>
<% current_user.following.each do |u| %>
<li><%= link_to u.username, u %></li>
<% end %>
</ul>
Followed By
<ul>
<% current_user.followers.each do |u| %>
<li><%= link_to u.username, u %></li>
<% end %>
</ul>
List Users<br />
<% if !#users.blank? %>
<% for #user in #users %>
<%= #user.username%><br />
<%= form_for #relation do |f| %>
<%= f.hidden_field :following_id, :value => #user.id %>
<%= f.submit "Follow" %>
<% end %>
<%end%>
<%else%>
<%end%>
when i click "follow" the following_id has been sent:(My current_user id = 9 )
{"utf8"=>"✓",
"authenticity_token"=>"NxOq/F5tOuElvhJNLOvkt/25enUN1wDI05I0fKp998Q=",
"relation"=>{"following_id"=>"11"},
"commit"=>"Follow"}
When i check Relation.all in rails console, the following_id has been insert, but when i check (as curent_user account)user.following - i see nothing, no following_id. I think something wrong in relation_controller at "current_user.following << follow".
I just can follow my current_user but it's ridiculous :)). So, please help me !!!!!!
You need to sanitize parameters before you can put things into the database.
Read more http://guides.rubyonrails.org/security.html
Related
I wanted know, how to post the values from the chat controller to other tables using rails.
class Chat < ApplicationRecord
belongs_to :user
has_many :visitors
has_many :themes
class Colour < ApplicationRecord
has_many :themes
has_many :chatbots, through: :themes
has_many :user_avatars, through: :themes
validates :hash_code, presence: true
class UserAvatar < ApplicationRecord
belongs_to :user
has_many :themes
has_many :chatbots, through: :themes
has_many :colours, through: :themes
validates :image_icon,:presence => true
class Theme < ApplicationRecord
belongs_to :chatbot
belongs_to :user_avatar
belongs_to :colour
validates :position, presence: true
Here in chat i should able to select colour, position, user avatar and it should be saved in those table, but here I dont know how to post the values from chat controller to other tables (for selecting the colour I am using color-picker)
code for chat_controller is given below
class ChatsController < ApplicationController
layout 'dashboard'
before_action :authenticate_user!
def index
#chatbot = Chatbot.all.where(:user_id => current_user.id)
end
def new
#chatbot = Chatbot.new
end
def show
#chatbot = Chatbot.find_by_id(params[:id])
end
def edit
#chatbot = Chatbot.find_by_id(params[:id])
end
def destroy
#chatbot = Chatbot.find_by_id(params[:id])
if #chatbot.destroy
flash[:success] = "Successfully deleted!"
else
flash[:success] = "Deletion Failed!"
end
end
def create
#colour = Colour.new(colour_params)
if #colour.save
redirect_to chatbots_path
end
end
private
def colour_params
params.require(:colour).permit(:hash_code)
end
def chatbot_params
params.require(:chatbot).permit(:id,:name,:description,:embed_id)
end
end
show.html.erb
<%= form_for #chatbot, :url => {:controller => 'chatbots', :action =>
"create" }, html: { method: :post } do |f| %>
<%= f.label "Select Theme Color" %>
<%= f.hidden_field :colour_ids %>
<%= f.text_field :colour, class: "color-picker", id: "theme-picker" %>
<%= f.submit "Save" , class: "btn btn-primary"%>
<% end %>
# code for position-select
# code for user avatar
I know this is a pretty standard error, but I could not figure out a solution to this particular solution from other questions.
I am following this coderwall tutorial about Creating a Scoped Invitation System for Rails.
I have four models, as follows:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
has_many :invitations, :class_name => "Invite", :foreign_key => 'recipient_id'
has_many :sent_invites, :class_name => "Invite", :foreign_key => 'sender_id'
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many :invites
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Invite < ActiveRecord::Base
belongs_to :calendar
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
And this is the migration for the Invite model:
class CreateInvites < ActiveRecord::Migration
def change
create_table :invites do |t|
t.string :email
t.integer :calendar_id
t.integer :sender_id
t.integer :recipient_id
t.string :recipient_role
t.string :token
t.timestamps null: false
end
end
end
The goal of the Invite model is to allow Users to invite other Users to join a particular Calendar.
The create Invite form is embedded in the Calendar edit view, as follows:
<h2>Edit <%= #calendar.name %> calendar</h2>
<%= render 'form' %>
<h2>Invite new users to <%= #calendar.name %> calendar</h2>
<%= form_for #invite , :url => invites_path do |f| %>
<%= f.hidden_field :calendar_id, :value => #invite.calendar_id %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label "Role" %>
<%= f.radio_button(:recipient_role, "Editor") %>
<%= f.label "Editor" %>
<%= f.radio_button(:recipient_role, "Viewer") %>
<%= f.label "Viewer" %>
<%= f.submit 'Send' %>
<% end %>
<%= link_to 'Show', calendar_path %> |
<%= link_to 'Back', calendars_path %>
Here is the corresponding Calendars#Edit:
def edit
#user = current_user
#invite = #calendar.invites.build
authorize #calendar
end
And here is the InvitesController:
class InvitesController < ApplicationController
def create
#invite = Invite.new(invite_params) # Make a new Invite
#invite.sender_id = current_user.id # set the sender to the current user
if #invite.save
InviteMailer.invite(#invite, new_user_registration_path(:invite_token => #invite.token)).deliver #send the invite data to our mailer to deliver the email
else
format.html { render :edit, notice: 'Invitation could not be sent.' }
end
end
private
def invite_params
params.require(:invite).permit(:email)
end
end
Last but not least, here is the InviteMailer:
class InviteMailer < ApplicationMailer
def invite(invite)
#link = new_user_registration_path invite_token: invite.token
mail to: invite.email, subject: "Calendy Invitation"
end
end
When I visit http://localhost:3000/calendars/3/edit and submit the Invite create form, I get the following error:
ArgumentError in InvitesController#create
wrong number of arguments (2 for 1)
class InviteMailer < ApplicationMailer
def invite(invite)
#link = new_user_registration_path invite_token: invite.token
mail to: invite.email, subject: "Calendy Invitation"
end
My instinct would be to replace:
InviteMailer.invite(#invite, new_user_registration_path(:invite_token => #invite.token)).deliver
With:
InviteMailer.invite(#invite).deliver
But I am not sure this is actually the right solution.
Any idea about how to fix this error?
May be changing the invite to allow an extra argument like below should work too
class InviteMailer < ApplicationMailer
def invite(invite, link)
#link = link
mail to: invite.email, subject: "Calendy Invitation"
end
end
My instinct would be to replace:
InviteMailer.invite(#invite, new_user_registration_path(:invite_token => #invite.token)).deliver
With:
InviteMailer.invite(#invite).deliver
Yes, that would be fine, since you're doing the same - your InviteMailer#invite stores this data itself in #link variable:
class InviteMailer < ApplicationMailer
def invite(invite)
#link = new_user_registration_path invite_token: invite.token
mail to: invite.email, subject: "Calendy Invitation"
end
end
The example line in here didn't work. I tried 20 varieties of it.
views/comments/_comments.html.erb
<% #comments.each do |comment| %>
<%= User.find(comment.user_id).name %> # Gives user name of commenter
<%= simple_format comment.content %>
<%= pluralize(comment.likes, 'like') %>
<%= link_to content_tag(:span, '', class: 'glyphicon glyphicon-thumbs-up') +
' Like it', like_comment_path(:id => comment.id), method: :post %>
<%= User.find(like.user_id).name %> # How to get user name of liker?
<% end %>
comments_controller.rb
def like
#comment = Comment.find(params[:id])
comment_like = current_user.comment_likes.build(comment: #comment)
if comment_like.save
#comment.increment!(:likes)
#comment.create_activity :like
#user = User.find(params[:id])
flash[:success] = 'Thanks for liking!'
else
flash[:error] = 'Two many likes'
end
redirect_to(:back)
end
comment_like.rb
class CommentLike < ActiveRecord::Base
belongs_to :comment
belongs_to :user
validates :user, uniqueness: { scope: :comment }
end
comment.rb
class Comment < ActiveRecord::Base
include PublicActivity::Common
# tracked except: :update, owner: ->(controller, model) { controller && controller.current_user }
has_many :comment_likes
has_many :likers, through: :comment_likes, class_name: 'User'
belongs_to :commentable, polymorphic: true
belongs_to :user
end
A comment has many likes. So you are looking for the comment likers.
class Comment
has_many :comment_likes
has_many :likers, through: :comment_likes, class_name: 'User', source: :liker
end
class CommentLikers
belongs_to :liker, class_name: 'User', foreign_key: :user_id
belongs_to :liked_comment, class_name: 'Comment', foreign_key: :comment_id
end
class User
has_many :comment_likes
has_many :liked_comments, through: :comment_likes, class_name: 'Comment', source: :liked_comment
end
Then in your views:
<% #comments.each do |comment| %>
<% comment.likers.each do |user| %>
<%= user.name %>
<% end %>
<% end %>
EDIT 1
Your question is so well explained in the rails guides:
http://guides.rubyonrails.org/association_basics.html
But just to give you a short explanation:
You need to associate the comments through the comment likes to the users. To do you need to tell rails to look for the user in the table using the user_id.
That's what the through: :comment_likes, class: 'User' do.
EDIT 2
Check the source code to see more options:
http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many
1) If like variable declared in controller it should be global: #like
2) Don't use User.find(comment.user_id).name or User.find(like.user_id).name.
Use it like comment.user.name, #like.user.name
The short answer
In your controller, change
comment_like = current_user.comment_likes.build(comment: #comment)
if comment_like.save
with
#comment_like = current_user.comment_likes.build(comment: #comment)
if #comment_like.save
In your view, change
<%= User.find(like.user_id).name %>
with
<%= #comment_like.user.name %>
I'm creating review to my posts, all works but i dont know how to show who wrote the review
i'm trying this:
class User < ActiveRecord::Base
has_many :posts
has_many :reviewers, :class_name => 'Post', :foreign_key => 'reviewer_id'
end
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :category
has_many :reviews
belongs_to :reviewers, class_name: 'User', :foreign_key => 'reviewer_id'
default_scope -> { order('created_at DESC') }
end
class Review < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
class ReviewsController < ApplicationController
def new
#post = Post.find(params[:post_id])
#review = #post.reviews.new(post_id:params[:post_id])
end
def create
#post = Post.find(params[:post_id])
#review = #post.reviews.build(review_params)
if #review.save
flash[:success] = "Ваш отзыв добавлен"
redirect_to post_path #post
else
render 'new'
end
end
private
def review_params
params.require(:review).permit(:post_id, :body, :reviewer_id).merge(:reviewer_id => current_user.id)
end
end
and my view
<% #post.reviews.each do |review| %>
<p>
<strong>reviewer:</strong>
<%= review.reviewer.email %>
</p>
<p>
<strong>review:</strong>
<%= review.body %>
</p>
<% end %>
my migration
class CreateReviews < ActiveRecord::Migration
def change
create_table :reviews do |t|
t.text :body
t.references :post, index: true
t.references :reviewer, index: true
t.timestamps
end
end
end
but rails given error undefined method `reviewer' for #
Help please dsfsdf
I think that you have a pluralization issue:
A post have many reviews by many reviewers (one for each review). But you are storing the foreign key within the post so you written the problematic line:
belongs_to :reviewers, class_name: 'User', :foreign_key => 'reviewer_id'
The issue here is that it is a singular association with a plural name.
I think that you are trying to say here that a
class Post
have_many :reviewers, class_name: 'User', through: :reviews
end
But as you are trying to access the reviewers from the review what you really need is to add:
class Review
belongs_to :reviewer, class_name: 'User'
end
Then you can access the reviewers from the review as expected:
<% #post.reviews.each do |review| %>
<p>
<strong>reviewer:</strong>
<%= review.reviewer.email %>
</p>
<p>
<strong>review:</strong>
<%= review.body %>
</p>
<% end %>
There is also an error in User:
has_many :reviewers, :class_name => 'Post', :foreign_key => 'reviewer_id'
As it should be:
has_many :reviews, :foreign_key => 'reviewer_id'
You need to be using .user. Check the belongs_to in your model.
Review.first.user
As a previous poster pointed out, your user association for Review is :user, so your view should probably look like this:
<% #post.reviews.each do |review| %>
<p>
<strong>reviewer:</strong>
<%= review.user.name unless review.user.nil? %>
</p>
<p>
<strong>review:</strong>
<%= review.body %>
</p>
<% end %>
My link_to in my view is going to a completely different "show.html.erb" than I'd like it to. I'm basically trying to understand why the "link_to #exhibit is linking to an "Investigation" profile. I think it may have to do with my routes file or the fact that its a "belong to" relationship...but can't seem to get it workin...what should that link_to be?
UPDATE: (AS PER BROIS QUESTION)
The missing misbehaving link_to is in the <%= link_to #exhibit do %> in show.html.erb
MY EXHIBIT.RB (MODEL)
class Exhibit < ActiveRecord::Base
attr_accessible :content, :investigation_id, :name, :user_id, :media, :media_html
belongs_to :investigation
has_many :categorizations
has_many :categories, :through => :categorizations
validates :name, presence: true, length: { maximum: 140 }
validates :content, presence: true
default_scope -> { order('created_at DESC') }
auto_html_for :media do
html_escape
image
youtube(:width => 400, :height => 250)
link :target => "_blank", :rel => "nofollow"
simple_format
end
MY EXHIBIT CONTROLLER:
class ExhibitsController < ApplicationController
include AutoHtml
def new
#exhibit = Exhibit.new
end
def show
#exhibit = Exhibit.find(params[:id])
end
def index
#exhibits = Exhibit.paginate(page: params[:page])
end
def create
#investigation = Investigation.find(params[:investigation_id])
#exhibit = #investigation.exhibits.create(params[:exhibit])
if #exhibit.save
flash[:success] = "You've successfully added etc etc..."
redirect_to investigation_path(#investigation)
else
render 'new'
end
end
end
MY ROUTES.RB
resources :sessions, only: [:new, :create, :destroy]
resources :investigations do
resources :players
end
resources :investigations do
resources :exhibits
end
LASTLY MY SHOW.HTML.ERB (INVESTIGATION PROFILE)
<% #investigation.exhibits.each do |exhibit| %>
<div class="row-fluid services_circles">
<%= link_to #exhibit do %>
<div class="media">
<div class="pull-left">
<%= exhibit.media_html %>
</div>
<div class="media-body">
<h4 class="media-heading"><%= exhibit.name %></h4>
<p><%= exhibit.content %></p>
</div>
</div>
<% end %>
<% end %>
ADDED THE INVESTIGATIONS CONTROLLER
class InvestigationsController < ApplicationController
def new
#investigation = Investigation.new
end
def show
#investigation = Investigation.find(params[:id])
end
def index
#investigations = Investigation.paginate(page: params[:page])
end
def create
#investigation = Investigation.new(params[:investigation])
if #investigation.save
flash[:success] = "You've successfully created..."
redirect_to #investigation
else
render 'new'
end
end
end
ADDED THE INVESTIGATION MODEL
class Investigation < ActiveRecord::Base
# belongs_to :user
has_many :players, dependent: :destroy
has_many :exhibits, dependent: :destroy
default_scope -> { order('created_at DESC') }
end
I appreciate the help...if i need to post any more info just let me know
IN YOUR : app/contorollers/exhibits_controller.rb
def show
#investigation = Investigation.find(params[:investigation_id])
#exhibit = Exhibit.find(params[:id])
end
IN YOUR : app/views/exhibits/show.html.erb
<%= link_to investigation_exhibit_path(#investigation, #exhibit) do %>
Maybe, I think.