I can't solve this problem.
When I try to use "Chatroom#new" method, I I got this error, ActionController::ParameterMissing param is missing or the value is empty .
below codes are the ChatroomController.
class ChatroomsController < ApplicationController
before_action :find_room_owner,only:[:index]
before_action :objects_for_index,only:[:index]
def index
#/users/:user_id/cart/items/chatroom
sign_in #user if signed_in?
if #seller && #buyer
flash[:success] = "U are owners of the chatroom"
#messages = Message.all #Messageのmodelを作成
else
flash[:error] = "U cant enter the chatroom."
redirect_to user_cart_items_url(#user,#cart,#items) ##user,#cart,#itemsをgetしろ
end
end
def new
#user = User.find(params[:user_id])
#cart = Cart.find(params[:user_id])
#item = Item.find(params[:item_id])
#message = Message.new(message_params)
end
def create
#user = User.find(params[:user_id])
#message = #user.messages.build
if #message.save
#message.update_attributes(user_id:#user.id)
redirect_to user_cart_chatroom_path(#user,#cart,#items)
else
flash[:error] = "could not create any message."
render 'new'
end
end
private
def message_params
params.require(:messages).permit(:id,:user_id,:messages)
#params{:message => :id,:user_id,:messages}
end
#before_aciton
def find_room_owner
#item = Item.find(params[:item_id])
#buyer = User.find(params[:user_id])
#seller = Product.find_by(user_id:#item.user_id)
end
def objects_for_index
#user = User.find(params[:user_id])
#items = Item.all
end
end
Below codes are the view of Message#new.
<h1>Chatroom#new</h1>
<p>Find me in app/views/chatroom/new.html.erb</p>
<%= form_for #message,url:new_user_cart_item_chatroom_path(#user,#cart,#item) do |f| %>
<%= f.label :messages %>
<%= f.text_field :messages %>
<%= f.submit "new message", class:"btn btn-default" %>
<% end %>
Below codes are the migration of Message.
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.integer :user_id
t.string :messages
t.timestamps
end
end
end
Below codes are the model of message.
class Message < ActiveRecord::Base
validates :messages,presence:true,length:{maximum:200}
belongs_to :user
end
Below codes are the routes.
KaguShop::Application.routes.draw do
resources :users,only:[:show,:new,:create,:edit,:update,:destroy] do
collection do
get 'get_images',as:'get_images'
end
resources :products,only:[:show,:index,:new,:create,:edit,:update,:destroy] do
collection do
post 'add_item', as:'add_item'
get 'get_image',as:'get_image'
get 'get_images',as:'get_images'
end
end
end
resources :users,only:[:show,:new,:create,:edit,:update,:destroy] do
resource :cart,except:[:new,:show,:edit,:destroy,:update,:create] do
collection do
post 'purchase', as:'purchase'
#get 'show' , as: 'show'
post 'create' , as: 'create'
#多分routeにas的な感じでtemplateを提供するのが一番いい気がする
delete 'destroy',as:'destroy'
delete 'remove_item',as:'remove_item'
end
resources :items,only:[:show,:index] do
collection do
get 'get_images',as:'get_images'
end
resources :chatrooms,only:[:index,:create,:new] do
end
end
end
end
resources :sessions,only:[:new,:create,:destroy]
root 'products#index'
match '/signup', to:'users#new',via:'get'
match '/signin', to:'sessions#new', via:'get'
match '/signout', to:'sessions#destroy', via:'delete'
match '/contact', to:'nomal_pages#contact', via:'get'
end
You should call Message.new without params because message_params nil in this request and this raise ActionController::ParameterMissing:
class ChatroomsController < ApplicationController
#.........
def new
#user = User.find(params[:user_id])
#cart = Cart.find(params[:user_id])
#item = Item.find(params[:item_id])
#message = Message.new
end
#........
private
def message_params
params.require(:messages).permit(:id,:user_id,:messages)
end
#.......
end
Related
I want to give an id of "paper model" to "schedules model" and create a note_id.
However an error message "no implicit conversion of Symbol into Integer" shows.
Can someone help me to solve this problem?
papers/index.html.erb
<%= link_to "Go to Schedule", new_schedule_path(id: paper.id) %>
routes.rb
get '/schedules/new/:id', to: 'schedules#new', as: :schedules_new
schedules_controller
class ActionsController < ApplicationController
before_action :authenticate_user!
before_action :set_schedule, only: [:edit, :update, :destroy]
def new
#schedule = Schedule.new
end
def create
#schedule = Schedule.new(schedule_params)
#schedule.user_id = current_user.id
#schedule.note_id = params[:id]
if #schedule.save
redirect_to schedules_path, notice: "A schedule was saved!"
end
end
def index
#schedules = Schedule.all
end
def update
end
def delete
end
Private
def schedule_params
params.require(:schedule).permit(:note_id, :user_id, :params[:id])
end
def set_schedule
#schedule = Schedule.find(params[:id])
end
end
params
=> "31", "controller"=>"schedules", "action"=>"new"} permitted: false>
You are not even using shedule_params values, as you override them afterwards ......
Then you could create empty Schedule object and then assign values ...
def create
#schedule = Schedule.new
#schedule.user_id = current_user.id
#schedule.note_id = params[:id]
if #schedule.save
redirect_to schedules_path, notice: "A schedule was saved!"
end
end
Or if I am correct with your relations, it could be also
def create
#schedule = current_user.schedules.new
#schedule.note_id = params[:id]
if #schedule.save
redirect_to schedules_path, notice: "A schedule was saved!"
end
end
I could solve this problem as follow.
Controller:
def new
#schedule = Schedule.new
#schedule.note_id = params[:id]
end
def create
#schedule = Schedule.new(schedule_params)
#schedule.user_id = current_user.id
if #schedule.save
redirect_to schedules_path, notice: "A schedule was saved!"
else
render 'new'
end
end
.
.
.
Private
def schedule_params
params.require(:schedule).permit(:note_id, :user_id)
end
Add into View
<%= f.hidden_field :id, :value => #schedule.note_id %>
I'm creating an app where u can see all conferences in the world.
What I've got:
creating an conference
showing all conferences
Now what I want to create is an button that let's me add a conference to a user.
What do I want to accomplish with this:
adding conference to users
showing added conferences in a list
viewing conferences and adding content
I was thinking of an button that copies the attributes of selected object and adds it to an selected user for future manipulation and viewing of the conference
I'm asking if someone can tell me how to accomplish this
https://consulegem-salman15.c9users.io/conferences
Migration conferences
class CreateConferences < ActiveRecord::Migration[5.0]
def change
create_table :conferences do |t|
t.string :conference
t.string :country
t.string :month
t.string :presence
t.string :audience
t.integer :cost
t.text :content
t.references :user, foreign_key: true
t.timestamps
end
add_index :conferences, [:user_id, :created_at]
end
end
Controller conference
class ConferencesController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
before_action :admin_user, only: :destroy
def index
#conferences = Conference.paginate(page: params[:page])
if params[:search]
#conferences = Conference.search(params[:search]).order("created_at DESC").paginate(page: params[:page])
else
#conferences = Conference.all.order('created_at DESC').paginate(page: params[:page])
end
end
def new
#user = User.new
#conference = Conference.new
end
def create
#conference = current_user.conferences.build(conference_params)
if #conference.save
flash[:success] = "conference created!"
redirect_to conferences_path
else
#feed_items = current_user.feed.paginate(page: params[:page])
render 'new'
end
end
def destroy
#conference.destroy
flash[:success] = "conference deleted"
redirect_to request.referrer || root_url
end
private
def conference_params
params.require(:conference).permit(:conference,:country , :month, :presence, :audience, :cost ,:picture)
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
def correct_user
#conference = current_user.conferences.find_by(id: params[:id])
redirect_to root_url if #conference.nil?
end
end
Model controller
class Conference < ApplicationRecord
belongs_to:user
default_scope -> { order(created_at: :desc) }
mount_uploader :picture, PictureUploader
validates :user_id, presence: true
validates :conference, presence: true, length: { maximum: 140 }
validate :picture_size
scope :conference, -> (conference) { where conference: conference }
def self.search(search)
where("conference LIKE ? OR country LIKE ? OR month LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
end
private
# Validates the size of an uploaded picture.
def picture_size
if picture.size > 5.megabytes
errors.add(:picture, "should be less than 5MB")
end
end
end
The answer I found was by adding a SubscriptionsController that is nested in the ConferenceController and a RelationshipController
SubscriptionController
class SubscriptionsController < ApplicationController
before_action :set_conference, only: :create
def index
#subscriptions = current_user.subscriptions
#subscriptions = Subscription.paginate(page: params[:page])
end
def show
#subscription = Subscription.find_by(id: params[:id])
end
def create
if current_user.subscriptions.create(conference: #conference)
flash[:success] = "You are now subscribed to { #conference.conference }"
else
flash[:error] = "Could not create subscription."
end
redirect_to conferences_path
end
def destroy
#subscription = current_user.subscriptions.find(params[:id])
if #subscription.destroy
flash[:success] = "You are no longer subscribed to { #conference.conference }"
else
flash[:error] = "Oh noes"
end
redirect_to conferences_path
end
def set_conference
#conference = Conference.find_by id: params["conference_id"]
end
end
RelationshipController
class RelationshipsController < ApplicationController
before_action :logged_in_user
def create
#conference = Conference.find(params[:followed_id])
current_user.follow(#conference)
respond_to do |format|
format.html { redirect_to #conference }
format.js
end
end
def destroy
#user = Relationship.find(params[:id]).followed
current_user.unfollow(#user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
end
end
ConferenceController
class ConferencesController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
before_action :admin_user, only: :destroy
def index
#conferences = Conference.paginate(page: params[:page])
if params[:search]
#conferences = Conference.search(params[:search]).order("created_at DESC").paginate(page: params[:page])
else
#conferences = Conference.all.order('created_at DESC').paginate(page: params[:page])
end
end
def show
#conference = Conference.find(params[:id])
end
def new
#user = User.new
#conference = Conference.new
end
def create
#conference = Conference.new(conference_params)
#conference.user = current_user
if #conference.save
flash[:success] = "conference created!"
redirect_to conferences_path
else
#feed_items = current_user.feed.paginate(page: params[:page])
render 'new'
end
end
def destroy
#conference.destroy
flash[:success] = "conference deleted"
redirect_to request.referrer || root_url
end
private
def conference_params
params.require(:conference).permit(:conference,:country , :month, :presence, :audience, :cost ,:picture)
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
def correct_user
#conference = current_user.conferences.find_by(id: params[:id])
redirect_to root_url if #conference.nil?
end
end
NameError in Comments#create
Showing /comments/_form.html.erb
where line #1 raised:
undefined local variable or method new_comment for #<#:0x007fb9760eb640>
<%= form_for new_comment, url: send(create_url, new_comment.commentable) do |f| %>
new_comment is being called by:
activities/index.html.erb
<%= render "comments/form", new_comment: Comment.new(commentable_id: activity.id, commentable_type: activity.class.model_name), create_url: :activity_comments_path %>
comment.rb
class Comment < ActiveRecord::Base
after_save :create_notification #ERROR OCCURRED WHEN I INTRODUCED THIS LINE AND
validates :activity, presence: true #THIS LINE
validates :user, presence: true
has_many :notifications
belongs_to :commentable, polymorphic: true
belongs_to :user
belongs_to :activity
private
def create_notification
Notification.create(
activity_id: self.activity_id,
user_id: self.user_id,
comment_id: self.id,
read: false
)
end
end
notification.rb
class Notification < ActiveRecord::Base
belongs_to :activity
belongs_to :comment
belongs_to :user
end
activity.rb
class Activity < ActiveRecord::Base
self.per_page = 20
has_many :notifications
belongs_to :user
has_many :comments, as: :commentable
belongs_to :trackable, polymorphic: true
def conceal
trackable.conceal
end
def page_number
(index / per_page.to_f).ceil
end
private
def index
Activity.order(created_at: :desc).index self
end
end
routes.rb
resources :activities do
resources :comments
resources :notifications
member do
post :like
post :notifications
end
end
Any ideas on what maybe the cause? This error is coming off of the awesome answer here: How to make a path to a paginated url?
Thank you!
UPDATE
class CommentsController < ApplicationController
before_action :load_commentable
before_action :set_comment, only: [:show, :edit, :update, :destroy, :like]
before_action :logged_in_user, only: [:create, :destroy]
def index
#comments = #commentable.comments
end
def new
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(comment_params)
if #comment.save
redirect_to #commentable, notice: "comment created."
else
render :new
end
end
def edit
#comment = current_user.comments.find(params[:id])
end
def update
#comment = current_user.comments.find(params[:id])
if #comment.update_attributes(comment_params)
redirect_to #commentable, notice: "Comment was updated."
else
render :edit
end
end
def destroy
#comment = current_user.comments.find(params[:id])
#comment.destroy
redirect_to #commentable, notice: "comment destroyed."
end
def like
#comment = Comment.find(params[:id])
#comment_like = current_user.comment_likes.build(comment: #comment)
if #comment_like.save
#comment.increment!(:likes)
flash[:success] = 'Thanks for liking!'
else
flash[:error] = 'Two many likes'
end
redirect_to(:back)
end
private
def set_comment
#comment = Comment.find(params[:id])
end
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
def comment_params
params[:comment][:user_id] = current_user.id
params.require(:comment).permit(:content, :commentable, :user_id, :like)
end
end
notifications_controller
class NotificationsController < ApplicationController
def index
#notifications = current_user.notifications
#notifications.each do |notification|
notification.update_attribute(:read, true)
end
end
def destroy
#notification = Notification.find(params[:id])
#notification.destroy
redirect_to :back
end
end
activities_controller
class ActivitiesController < ApplicationController
def index
#activities = Activity.order("created_at desc").paginate(:page => params[:page])
end
def show
redirect_to(:back)
end
def like
#activity = Activity.find(params[:id])
#activity_like = current_user.activity_likes.build(activity: #activity)
if #activity_like.save
#activity.increment!(:likes)
flash[:success] = 'Thanks for liking!'
else
flash[:error] = 'Two many likes'
end
redirect_to(:back)
end
end
It should be <%= form_for comment do |f| %> not new comment since comment is the element in your database
How can we limit a user to 1 like per comment?
comments_controller.rb
def like
#comment = Comment.find(params[:id])
#comment.increment!(:likes)
#comment.create_activity :like
flash[:success] = 'Thanks for liking!'
redirect_to(:back)
end
_comments.html.erb
<% #comments.each do |comment| %>
<%= User.find(comment.user_id).name %>
<%= 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 %>
<% end %>
valuation.rb
class Valuation < ActiveRecord::Base
belongs_to :user
has_many :comments, as: :commentable
include PublicActivity::Model
tracked owner: ->(controller, model) { controller && controller.current_user }
end
routes.rb
resources :valuations do
resources :comments
member do
post :like
end
end
I followed along this tutorial: http://www.sitepoint.com/activity-feeds-rails/ to implement the public_activity gem and the like button.
Thank you for your time and expertise!
UPDATE
class CommentsController < ApplicationController
before_action :load_commentable
before_action :set_comment, only: [:show, :edit, :update, :destroy, :like]
before_action :logged_in_user, only: [:create, :destroy]
def index
#comments = #commentable.comments
end
def new
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(comment_params)
if #comment.save
#comment.create_activity :create, owner: current_user
redirect_to #commentable, notice: "comment created."
else
render :new
end
end
def edit
#comment = current_user.comments.find(params[:id])
end
def update
#comment = current_user.comments.find(params[:id])
if #comment.update_attributes(comment_params)
redirect_to #commentable, notice: "Comment was updated."
else
render :edit
end
end
def destroy
#comment = current_user.comments.find(params[:id])
#comment.destroy
#comment.create_activity :destroy, owner: current_user
redirect_to #commentable, notice: "comment destroyed."
end
def like
#comment = Comment.find(params[:id])
#comment.increment!(:likes)
#comment.create_activity :like
flash[:success] = 'Thanks for liking!'
redirect_to(:back)
end
private
def set_comment
#comment = Comment.find(params[:id])
end
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
def comment_params
params[:comment][:user_id] = current_user.id
params.require(:comment).permit(:content, :commentable, :user_id)
end
end
comment.rb
class Comment < ActiveRecord::Base
include PublicActivity::Common
# tracked except: :update, owner: ->(controller, model) { controller && controller.current_user }
belongs_to :commentable, polymorphic: true
belongs_to :user
end
I think you could create additional model:
class CommentLike
belongs_to :comment
belongs_to :user
validates :user, uniqueness: { scope: :comment}
end
class User
has_many :comment_likes
end
class Comment
has_many :comment_likes
end
def like
#comment = Comment.find(params[:id])
if current_user.comment_likes.create(comment: #comment)
#comment.increment!(:likes)
#comment.create_activity :like
flash[:success] = 'Thanks for liking!'
else
flash[:error] = 'Two many likes'
end
redirect_to(:back)
end
It'll solves you problem. If storing likes_count in comment is neccessary, you could use Rails' counter_cache.
I added a link_to method to the view to allow users to select messages from the inbox to delete. I am using the Mailboxer gem. The error I receive when adding the code is ActiveRecord::RecordNotFound Couldn't find Conversation without an ID. Error points to the controller on line #conversation ||= mailbox.conversations.find(params[:id])
index.html.slim:
ul.right
li
= link_to 'Move to trash', [:trash, conversation], method: :post
img alt="" src="/assets/del_icon.png" /
li
input type="checkbox" class='select_conversations'
Conversations controller:
helper_method :mailbox, :conversation
before_filter :conversation, only: :show
before_filter :check_has_access
def index
#user = current_user
sentbox_page = params[:page] if params[:sentbox].present?
inbox_page = params[:page] if params[:inbox].present?
mailbox = #user.mailbox
#inbox = mailbox.inbox.paginate(:page => inbox_page, :per_page => 5)
#sentbox = mailbox.sentbox.paginate(:page => sentbox_page, :per_page => 5)
render layout: 'new_application'
end
def show
user = current_user
#receipts = conversation.receipts_for(user).paginate(:page => params[:page], :per_page => 5)
#conversation.receipts.recipient(user).update_all(is_read: true)
respond_to do |format|
format.html {render layout: 'new_application'}
format.js {}
end
end
def reply
current_user.reply_to_conversation(conversation, *message_params(:body, :subject))
redirect_to conversation
end
def trash_folder
#trash ||= current_user.mailbox.trash.all
end
def trash
conversation.move_to_trash(current_user)
redirect_to :conversations
end
def untrash
conversation.untrash(current_user)
redirect_to :conversations
end
def empty_trash
current_user.mailbox.trash.each do |conversation|
conversation.receipts_for(current_user).update_all(:deleted => true)
end
redirect_to :conversations
end
private
def mailbox
#mailbox ||= current_user.mailbox
end
def conversation
#conversation ||= mailbox.conversations.find(params[:id])
end
def conversation_params(*keys)
fetch_params(:conversation, *keys)
end
def message_params(*keys)
fetch_params(:message, *keys)
end
def fetch_params(key, *subkeys)
params[key].instance_eval do
case subkeys.size
when 0 then self
when 1 then self[subkeys.first]
else subkeys.map{|k| self[k] }
end
end
end
protected
def check_has_access
redirect_to(root_url) unless Subscription.exists?(user_id: current_user.try(:id) || -1, cancelled: nil)
end
end
The error is caused by the combination of these lines.
# in the controller
helper_method :mailbox, :conversation
# in the view
= link_to 'Move to trash', [:trash, conversation], method: :post
What happens is that the conversation variable called in the view is the controller method. Since you're in the index page, you don't have a params[:id] which causes find to raise the exception.
The easiest solution would be to remove conversation as a helper and just use #conversation in the view.