Rails 4 welcome wizard, how to correct this code to make it work for rails 4? - forms

Try to build a welcome wizard and try to get existing rails code to be ported to be rails 4 compatible. Based mostly on previous great answer: https://stackoverflow.com/a/17255451/355281
I try to call http://books:3000/welcome/basics
This results in:
Circular dependency detected while autoloading constant WelcomeController
app/controllers/welcome_controller.rb
class Welcome::ApplicationController < ::ApplicationController
layout "welcome"
before_filter :authentice_user!
end
app/controllers/welcome_basics_controller.rb
class Welcome::BasicsControlller < Welcome::ApplicationController
before_action :authenticate_user!
before_filter :allowed?
def new
#step = Welcome::Basics.new(current_user)
end
def create
#step = Welcome::Basics.new(current_user)
if #step.save(params[:welcome_basics])
redirect_to welcome_some_other_step_path, :notice => "Yay"
else
render :new
end
end
private
def step
#step ||= Welcome::Basics.new(current_user)
end
helper_method :step
def allowed?
redirect_to previous_step_path unless step.allowed?
end
end
**app/models/welcome_basics.rb
class Welcome::Basics
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
def persisted?
false
end
def initialize(user)
#user = user
end
attr_reader :user
delegate :some_field, :some_other_field, :to => :user
validates_presence_of :some_field
def save(params)
user.some_field = params[:some_field]
user.some_other_field = params[:some_other_field]
if valid?
user.step = 2
user.save
end
end
def photo
#photo ||= Photo.new
end
def profile
#profile ||= user.profiles.first
end
end
/config/routes.rb
namespace :welcome do
resource :basics, :only => [:new, :create]
end

I see a few things that appear to be off. The one that appears to be the biggest issue with Rails 4 vs Rails 3.2 is in your pseudo-model definition.
class Welcome::Basics
include ActiveModel::Model # Necessary for Rails 4
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
...
end
In your welcome_controller.rb, you have authentice user which should read authenticate user.
In your welcome_basics_controller.rb you misspelled controller in your definition, currently: Welcome::BasicsControlller should be Welcome::BasicsController.
I'd also recommend that you change your naming and inheritance to be a bit simpler and more inline with Rails convention over configuration. This would be my approach:
Since welcome_basics.rb is a pseudo-model, I'd put it in its own directory to prevent any potential automatic sourcing of ActiveModel. I'd also change the name to the singular to be in line with Rails conventions for models.
app/pseudo_models/welcome_basic.rb
class WelcomeBasic
include ActiveModel::Model # Necessary for Rails 4
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
...
end
Now I'd put your welcome_controller in a sub-directory called "welcome" within the controller directory:
app/controllers/welcome/welcome_controller.rb
class Welcome::WelcomeController < ApplicationController
layout "welcome"
before_filter :authenticate_user!
end
Then your basics controller should be called basics within the "welcome" directory, and since your inheriting from your welcome controller, you don't need to repeat the authenticate_user! line. Also remember that you'll need to rename your calls to your pseudo-model from Welcome::Basics to WelcomeBasic. For Rails 4 you'll also need to implement strong params in your controller.
app/controllers/welcome/basics_controller.rb
class Welcome::BasicsController < Welcome::WelcomeController
before_filter :allowed?
def new
#step = WelcomeBasic.new(current_user)
end
def create
#step = WelcomeBasic.new(current_user)
if #step.save(basic_params) #updated to use strong_params
redirect_to welcome_some_other_step_path, :notice => "Yay"
else
render :new
end
end
private
#For strong_params
def basic_params
params.require(:welcome_basic).permit(:attribute1, :attribute2)
end
def step
#step ||= WelcomeBasic.new(current_user)
end
helper_method :step
def allowed?
redirect_to previous_step_path unless step.allowed?
end
end
/config/routes.rb
...
namespace :welcome do
resources :basics, :only => [:new, :create]
end
...
The other thing that you'll need to ensure is that your corresponding views are placed within the same directory structure as your controller, so you should have the following:
/app/views/welcome/basics/welcome.html.erb
One other note, when you say "I try to call http://books:3000/welcome/basics", I assume you mean that your attempting to post your form? Otherwise, you should be calling http://books:3000/welcome/basics/new in order to get your basics form. If you want that route to map to http://books:3000/welcome/basics you'll need to make the corresponding adjustments in your config/routes.rb file.

Related

RAILS 4 After editing and updating, the id of posts is passed as user why?

I have a user model that has_many posts, but I have few issues when a user updates a post. When a first user (user id:1) updates a post, (say post id:13), upon redirect, the page tries to redirect to user id:13. Does anyone know why this is? Here are my lines of code.. Thanks in advance.
posts_controller.rb
.
.
.
def update
#post = current_user.posts.find(params[:id])
if #post.update_attributes(post_params)
redirect_to user_path, notice: "Successfully updated!"
else
render action: "edit"
end
end
users_controller.rb
.
.
.
def show
#user = User.find(params[:id])
#posts = #user.posts.paginate(page: params[:page])
end
redirect_to **user_path**, notice: "Successfully updated!"
You are redirecting to the user_path. You want to redirect to the post_path. Unless what you want is directing to the user_path. Then, you need to pass it the user id: user_path(current_user.id)

Sinatra and "controllers" behaviour

Sinatra from Box does't allow separate action to file? Like this:
index.php
get '/' and other
user.php
get '/user/show/'
post '/user/new/' and other
How to say sinatra use user.php for '/user/*' request, and index.php for '/'.
And how looks application with many get post in one file written in sinatra? (one huge ass?)
After reading a lot, exist some solution:
1.
class Get < Sinatra::Base
get('/') { 'GET!' }
end
class Post < Sinatra::Base
post('/') { 'POST!' }
end
class Routes < Sinatra::Base
get('/') { Get.call(env) }
post('/') { Post.call(env) }
end
run Routes
2.
class Foo < Sinatra::Base
get('/foo') { 'foo' }
end
class Bar < Sinatra::Base
get('/bar') { 'bar' }
end
Routes = Rack::Mount::RouteSet.new do |set|
set.add_route Foo, :path_info => %r{^/foo$}
set.add_route Bar, :path_info => %r{^/bar$}
end
run Routes

rhomobile prepopulated DB and reset

Hi I am prepopulating the db as said here
http://docs.rhomobile.com/faq#how-to-pre-populate-client-database
but I have a problem, that when I make reset DB with default code
def do_reset
Rhom::Rhom.database_full_reset
SyncEngine.dosync
#msg = "Database has been reset."
redirect :action => :index, :query => {:msg => #msg}
end
then I am losing the data. How can I make that the prepopulated database alsways will be loaded, when I make reset.
Cheers
I come up with such solution
in view do_reset.erb
<%
Antwort.delete_all()
file_name = File.join(Rho::RhoApplication::get_model_path('app','Settings'), 'antwort.txt')
file = File.new(file_name,"r")
aid=0
file.each_line("\n") do |row|
col = row.split("|")
aid=aid+1
#antwort=Antwort.create(
{"aid" => aid, "qid" => col[0],"antwort"=>col[1],"richtig"=>col[2]}
)
qty=file.lineno
break if file.lineno > 3000
end
Questions.delete_all()
file_name = File.join(Rho::RhoApplication::get_model_path('app','Settings'), 'questions.txt')
file = File.new(file_name)
file.each_line("\n") do |row|
col = row.split("|")
#question=Questions.create(
{"id" => col[0], "question" => col[1],"answered"=>'0',"show"=>'1',"tutorial"=>col[4]}
)
break if file.lineno > 1500
end
file.close
#msg="OK"
%>
But only problem I have now is single quotes aka ' in the texts. They are then displayed in app as a triangle with ? inside like � one. What to do?
You can seed the database using a pipe delimited text file, as explained here.
So, in the instance you are using the Property Bag model definitions, you will have a file called object_values.txt and load up whichever sources, properties, and values necessary.

Write Web call for iphone in ruby on rail. I want to get json formate and send response but formate of json is incorrect

I have a bug in the following Rails code which I cannot find. Any help would be appreciated.
class Api::ItemsController < ApplicationController
respond_to :json
def create
begin
#puts "params: #{params}"
if params[:item_post][:user][:uid] && params[:item_post][:user][:provider]
#user = User.find_by_provider_and_uid(params[:item_post][:user][:provider], params[:item_post][:user][:uid])
elsif params[:item_post][:user][:token]
#user = User.create_with_token(params[:item_post][:user][:token])
elsif params[:item_post][:user][:email]
#user = User.find_by_email(params[:item_post][:user][:email])
end
if #user
#item = #user.items.new(params[:item_post][:item])
else
#item = Item.new(params[:item_post][:item])
#item.reply_email = params[:item_post][:user][:email]
end
if #item.save
if params[:item_post][:item_images]
params[:item_post][:item_images].each_value do |item_image|
#item.images.create(item_image)
end
end
respond_with(#item)
else
#puts "Errors 1: #{#item.errors}"
respond_with(#item.errors)
end
rescue => e
#puts "Errors 2: #{e.message}"
respond_with(e.message.to_json, :status => :unprocessable_entity)
end
end
end
Problem:
I have been looking into the parameters received by the server. And I've tried to find the code where the parameters are built. Where can I find it?
In the server logs I can see the post as:
{"item_post":"{\"item\":{\"title\":\"Apple TV\",\"price\":\"45.50\",\"description\":\"Dual-Shielded High Speed HDMI Cable with Ethernet 2M are sold yesterday\",\"zipcode\":\"94102\"},\"user\":{\"email\":\"user#email.com\"}}}
I was expecting the post to look like this:
{\"item_post\":{\"item\":{\"title\":\"Apple TV\",\"price\":\"45.50\",\"description\":\"Dual-Shielded High Speed HDMI Cable with Ethernet 2M are sold yesterday\",\"zipcode\":\"94102\"},\"user\":{\"email\":\"user#email.com\"}}}
It seems to me that the 'item_post' block is being wrapped in unnecessary quotes, making it a string instead of a JSON hash:
I think this:
{"item_post":"{
should look like (no quote) this:
{"item_post":{
I am only guessing to what the problem could be.
I think you need avoid the to_json in your rescue
respond_with(e.message.to_json, :status => :unprocessable_entity)
put
respond_with(e.message, :status => :unprocessable_entity)
In your case the to_json before the to_json in the respond_with return a String it's why you have a String convert in JSON and not your Hash convert in JSON

How to allow custom flash keys in a redirect_to call in Rails 3

In Rails 3, you can pass has attributes directly to redirect_to to set the flash. For example:
redirect_to root_path, :notice => "Something was successful!"
However, this only works with the :alert and :notice keys; if you want to use custom keys, you have to use a more verbose version:
redirect_to root_path, :flash => { :error => "Something was successful!" }
Is there any way to make it so that custom keys (such as :error, above) can be passed to redirect_to without specifying it in :flash => {}?
In Rails 4 you can do this
class ApplicationController < ActionController::Base
add_flash_types :error, ...
and then somewhere
redirect_to root_path, error: 'Some error'
http://blog.remarkablelabs.com/2012/12/register-your-own-flash-types-rails-4-countdown-to-2013
I used the following code, placed in lib/core_ext/rails/action_controller/flash.rb and loaded via an initializer (it's a rewrite of the built-in Rails code):
module ActionController
module Flash
extend ActiveSupport::Concern
included do
delegate :alert, :notice, :error, :to => "request.flash"
helper_method :alert, :notice, :error
end
protected
def redirect_to(options = {}, response_status_and_flash = {}) #:doc:
if alert = response_status_and_flash.delete(:alert)
flash[:alert] = alert
end
if notice = response_status_and_flash.delete(:notice)
flash[:notice] = notice
end
if error = response_status_and_flash.delete(:error)
flash[:error] = error
end
if other_flashes = response_status_and_flash.delete(:flash)
flash.update(other_flashes)
end
super(options, response_status_and_flash)
end
end
end
You can, of course, add more keys besides just :error; check the code at http://github.com/rails/rails/blob/ead93c/actionpack/lib/action_controller/metal/flash.rb to see how the function looked originally.