I'm trying to follow wicked tutorial for creating an object partially
( https://github.com/zombocom/wicked/wiki/Building-Partial-Objects-Step-by-Step )
The problem is, I am having trouble creating the object itself. I've tried with and without strong params, or even making the call out of the controller, but can get it passed. What am I doing wrong?
class ProspectsController < ApplicationController
include Wicked::Wizard
steps :signup, :business_details, :user_details
def show
create_prospect if params[:prospect_id].nil?
byebug # => prospect_id is no appearing => Not_found
#prospect = Prospect.find(params[:prospect_id])
render_wizard
end
def update
#prospect = Prospect.find(params[:prospect_id])
params[:prospect][:status] = 'users_detailed' if step == steps.last
#prospect.update_attributes(params[:prospect])
render_wizard #prospect
end
def create_prospect
#prospect = Prospect.create
new_prospect_build_path(prospect_id: #prospect.id)
end
# def prospect_params
# params.require(:prospect).
# permit(:user_first_name, :user_last_name, :user_email, :dni, :plan, :empresa_name, :empresa_email,
# :empresa_phone, :empresa_address, :empresa_web, :empresa_category, :empresa_summary, :user_birthday,
# :user_phone, :user_address, :sex, :iban_code, :status, :prospect_id)
# end
end
Routes:
resources :prospects, only: [:show, :update] do
resources :build, controller: 'prospects'
end
you're using same controller action for two routes:
GET /prospects/:prospect_id/build/:id => prospects#show
GET /prospects/:id => prospects#show
same with update.
If you will get to that controller by GET prospect_path you will not get :prospect_id, but :id.
Related
I am using fragment caching in my rails 4 project. I have cities controller and city_sweeper
cities_controller.rb
cache_sweeper :city_sweeper, :only => [:update, :destroy]
.
.
def update_featured
#city = City.unscoped.find(params[:id])
if params[:featured]
#city.update_attribute(:featured, params[:featured])
end
render :text => "success:
end
.
end
and in my city_sweeper.rb I have this code
class CitySweeper < ActionController::Caching::Sweeper
observe City
def after_update(city)
expire_cache(city)
end
def after_destroy(city)
expire_cache(city)
end
def after_update_featured(city)
expire_cache(city)
end
def expire_cache(city)
expire_fragment "city_index_#{city.id}"
end
end
its working fine with CRUD operation, but its not working for my custom method.its calling my sweeper.rb , but I am not getting city object there. I am getting this error:
NoMethodError (undefined method `expire_fragment' for #<CitySweeper:0xab9f1e0 #controller=nil>):
You can expire the fragment cache using this
UPDATE
if #cities.present?
#cities.each do |city|
cache(action: 'recent_update',key: "city_index_#{city.id}", skip_digest: true) do
...
end
end
end
In Sweeper
class CitySweeper < ActionController::Caching::Sweeper
observe City
.....
def expire_cache(city)
expire_fragment(controller: 'cities', action: 'recent_update',key: "city_index_#{city.id}")
end
end
I want to change the status of hotels in my site. When user create new hotel, he have status "pending". As an administrator, I can upgrade the hotel status from pending to approved or rejected. But I can not approved of in the rejected and vice versa.
I decided to do it with three buttons in admin panel in the place where showing all hotels but this code not working.
routes.rb
HotelAdvisor::Application.routes.draw do
devise_for :admins
devise_for :users
devise_scope :admin do
get '/admin', to: 'devise/sessions#new'
end
post '/rate' => 'rater#create', :as => 'rate'
root to: 'hotels#list'
resources :hotels do
resources :comments
get 'list', on: :collection
post 'comment'
end
resources :ratings, only: :update
namespace :admin do
resources :hotels, :users
end
base_controller
class Admin::BaseController < ApplicationController
before_filter :authenticate_admin!
layout 'admin'
end
hootels_controller(in admin folder)
class Admin::HotelsController < Admin::BaseController
def index
#hotels = Hotel.all
end
def new
#hotel = Hotel.new
end
def create
#hotel = Hotel.new(hotel_params)
#hotel.user_id = current_admin.id
if #hotel.save
render :index
else
render :new
end
end
def update
#hotel = Hotel.find(params[:id])
#hotel.update_attributes(params[:hotel])
end
end
index(in /admin/hotels)
- #hotels.each do |hotel|
.ui.segment
.ui.three.column.grid
.column
.ui.large.image
=image_tag hotel.avatar_url
=link_to hotel_path(hotel), class:'blue ui corner label' do
%i.fullscreen.icon
.column
.ui.message
.header
=hotel.title
.wraper=hotel.description.truncate(300)
.column
=simple_form_for Hotel.find([hotel.id]),:method => :put do |f|
=f.hidden_field :status, value: 'approved'
=f.button :submit, 'Approved', class: 'secondary button'
%br
%hr
I don't know why, but I see this error,
Missing template hotels/update, application/update with...
I think out that in updating rails do not use the controller in the folder admin. Perhaps this is causing the error
Given you didn't implement what to be done, e.g. render, redirect, etc. rails fallbacks to the default, which is to render views with the name of the action, in this case, update.
You might want to take some action, depending on the outcome of update_attributes, for instance:
if #hotel.update_attributes(params[:hotel])
redirect_to(#hotel)
else
render(:edit)
end
You might also want to take a look at Responders to DRY your actions.
I've been building messaging in a rails app for users to be able to send each other messages. I've looked at a few gems such as mailboxer but ultimately decided to build my own.
I'm hoping someone can help me put these pieces together. I've been following a similar question's answer here.
I'm testing in the rails console and I keep getting the following error:
undefined method `send_message' for #
How can I fix this?
Controller
class MessagesController < ApplicationController
# create a comment and bind it to an article and a user
def create
#user = User.find(params[:id])
#sender = current_user
#message = Message.send_message(#sender, #user)
flash[:success] = "Message Sent."
flash[:failure] = "There was an error saving your comment (empty comment or comment way to long)"
end
end
Routes
resources :users, :except => [ :create, :new ] do
resources :store
resources :messages, :only => [:create, :destroy]
end
Messages Model
class Message < ActiveRecord::Base
belongs_to :user
scope :sent, where(:sent => true)
scope :received, where(:sent => false)
def send_message(from, recipients)
recipients.each do |recipient|
msg = self.clone
msg.sent = false
msg.user_id = recipient
msg.save
end
self.update_attributes :user_id => from.id, :sent => true
end
end
You are invoking the method on a class level: Message.send_message. For this to work, it would expect a declaration like this:
def self.send_message(from, recipients)
# ...
end
But, you got this instead:
def send_message(from, recipients)
# ...
end
So, either invoke the method on the instance you need it for, or refactor to make it work on a class level.
I am trying to integrate forem with thumbs_up. I have inherited the forem Post model and controller.
Here is my controller :-
class PostsController < Forem::PostsController
def vote_up
begin
current_user.vote_for(#post = Post.find(params[:id]))
render :nothing => true, :status => 200
rescue ActiveRecord::RecordInvalid
render :nothing => true, :status => 404
end
end
end
Here is how the Post Controller of Forem looks like :-
module Forem
class PostsController < Forem::ApplicationController
before_filter :authenticate_forem_user
before_filter :find_topic
.
.
.
.
private
def find_topic
#topic = Forem::Topic.find(params[:topic_id])
end
end
end
Here is my routes:-
mount Forem::Engine, :at => "/forums"
resources :posts do
member do
post :vote_up
end
end
Here is my view :-
<%= link_to t('vote for this post!', :scope =>"forem.post"), main_app.vote_up_post_path(#post), :method => :post %>
This is the error which I am getting :-
ActiveRecord::RecordNotFound in PostsController#vote_up
Couldn't find Forem::Topic without an ID
What could be the issue?
Your problem is the before filter:
module Forem
class PostsController < Forem::ApplicationController
#...
before_filter :find_topic
#...
def find_topic
#topic = Forem::Topic.find(params[:topic_id])
end
and then:
class PostsController < Forem::PostsController
def vote_up
#...
So find_topic will be called before vote_up but the route for vote_up won't have a :topic_id; no :topic_id means that find_topic will be doing this:
#topic = Forem::Topic.find(nil)
and that's where your error comes from.
Three options come to mind:
Move vote_up to a separate controller class that doesn't inherit from Forem::ApplicationController.
Add a skip_filter :find_topic, :only => :vote_up to PostsController.
Adjust the route and link to get a :topic_id in the route.
If upvoting doesn't need the #topic then (1) or (2) would work, otherwise you'll have to go with (3).
check rake routesin command prompt,
and check id should be post :vote_up OR get:vote_up – ror_master
and use debugger in controller!
and write params there perhaps you will get solution.
I have the following in my controller for Attachment
def upload
#attachment = Attachment.build(:swf_uploaded_data => params[:attachment][:attachment], :user_id => current_user.id, :project_id => params[:space_id])
....
end
What I'd like from CanCan is to only allow users to upload to a project_id they belong to. I confirmed the controller is getting the correct info, no nils
Here is my cancan:
can :upload, Attachment do |attachment|
Rails.logger.info 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX- include CanCan::Ability - ATTACHMENT'
Rails.logger.info attachment.inspect
Rails.logger.info attachment.project
current_user.try(:role, attachment.space)
end
Problem here, is that attachment. is nil, and attachment.project is nil? How do you solve for this issue with CanCan so I can make sure only project teammembers can upload attachments to the project?
Thank you
I think the best approach it to do it at a lower level with the authorize! method that the Controller action.
So ...
#AttachmentController
#Will remove it from cancan
load_and_authorize_resource :except => [:upload]
def upload
#attachment = Attachment.build(:swf_uploaded_data => params[:attachment][:attachment], :user_id => current_user.id, :project_id => params[:space_id])
#add the authorize logic explicitly here when you have the attachment model populated
authorize! :upload, #attachment
end
Let me know if that works for you.
For example if you want to allow create events for current loop only:
You use in the view
link.... if can? :create, #loop.events.new
and then in controller
skip_authorize_resource only: [:new, :create]
...
def new
#event.loop_id = #loop.id
authorize! :create, #event
end
#similar for create action