I'm new to Rails and indeed to web development. I'm trying to do a cross-domain post (I think) and have no clue how to do it.
I have a rails app running on webrick, let's call this 'myapp'.
I have written a bookmarklet which when selected should grab the URL from whatever website the user is on and post it to 'myapp' to be saved for that user (who will need to give his email address). How would I write a controller to deal with this?
It's hard to be specific with the amount of info you've provided, but general, you'll need to set up a route to handle the request, and define a controller action to do what you want with it.
Assuming the requests look something like POST http://myapp.com/bookmarks/create with parameters for the user's email and the url they're on, that means doing something like this:
in routes.rb:
resources :bookmarks
in bookmarks_controller.rb:
def create
if params[:email]
#user = User.find_by_email(params[:email])
if #user
#user.bookmarks.create!(:url => params[:url]
end
end
end
Related
I'm running a rails 4 app using Omniauth with Twitter. I'm trying to achieve something close to producthunt.com, where they authenticate users and use their Twitter username as their url id.
From what I understand, you want the url to look like this: example.com/users/username
instead of example.com/users/123
If so, all you have to do is change the way you find the de correct user in your Users (or whatever you call your user model) controller. Currently it probably looks like this:
#Users Controller
def show
#user = User.find(params[:id])
end
# Your path to that user is probably this:
user_path(123) #basically you pass the user.id
The code above is using Model.find(#) to look for the user. The .find() looks the user up by its id#. Instead, you want to find it by the username, not id. To do this use the Model.find_by You can see all the ways of querying here.
Also, whenever you look for the path to find the user show page, istead of sending the id # to the url, you now have to send the username string.
Your new setup should look like this:
#Users Controller
def show
#user = User.find_by :username params[:id]
#this assumes you have it in your DB as username. Some twitter apps save it as screen_name.
end
# Your path to that user is probably this:
user_path('username') #basically you pass the username instead. current_user.username? I dont know what you call in in your app.
Hope that helps. Let me know if you have questions.
I am a newbie in the world of ruby on rails, and trying to find out how routing works. I read some articles about it but something is not clear to me.
If I have a page, with a message sender form and try to send the data via post, I have to set the route sg like this:
post '/send', to: 'message#send'
with this it works fine. But what if I have an another page with another form and I want to link it to another controller/action(post request too). How can It make a disctinction between the 2 posts?
You can pass some special parameter and check it's value in controller, for instance:
class MessageController < ApplicationController
def send
if params[:kind] == 'some_value'
do_one_thing
else
do_anoter_thing
end
end
end
But in this case your action will become fat and ugly. Thus I suggest you to create new action and separate logic in a natural way:
post '/my_send_from_one_place', to: 'message#my_send_from_one_place'
post '/my_send_from_secong_place', to: 'message#my_send_from_secong_place'
StackOverflow seems to have this style of routes for questions:
/questions/:id/*slug
Which is easy enough to achieve, both in routes and to_param.
However, StackOverflow seems to also redirect to that path when just an ID is passed.
Example:
stackoverflow.com/questions/6841333
redirects to:
stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result/
Same goes for any variation of the slug
stackoverflow.com/questions/6841333/some-random-stuff
Will still redirect to the same URL.
My question is: Is this type of redirection typically handled in the controller (comparing the request to the route) or is there a way to do this in routes.rb?
The reason I wouldn't think this possible in the routes.rb file is that typically, you don't have access to the object (so you couldn't get the slug based off the ID, right?)
For anyone interested, Rails 3.2.13 and also using FriendlyID
Ok, so I think I've got this.
I was looking into doing something with middleware, but then decided that's probably not the place for this type of functionality (since we need to access ActiveRecord).
So I ended up building a service object, known as a PathCheck. The service looks like this:
class PathCheck
def initialize(model, request)
#model = model
#request = request
end
# Says if we are already where we need to be
# /:id/*slug
def at_proper_path?
#request.fullpath == proper_path
end
# Returns what the proper path is
def proper_path
Rails.application.routes.url_helpers.send(path_name, #model)
end
private
def path_name
return "edit_#{model_lowercase_name}_path" if #request.filtered_parameters["action"] == "edit"
"#{model_lowercase_name}_path"
end
def model_lowercase_name
#model.class.name.underscore
end
end
This is easy enough to implement into my controller:
def show
#post = Post.find params[:post_id] || params[:id]
check_path
end
private
def check_path
path_check = PathCheck.new #post, request
redirect_to path_check.proper_path if !path_check.at_proper_path?
end
My || in my find method is because in order to maintain resourceful routes, I did something like...
resources :posts do
get '*id' => 'posts#show'
end
Which will make a routes like: /posts/:post_id/*id on top of /posts/:id
This way, the numeric id is primarily used to look up the record, if available. This allows us to loosely match /posts/12345/not-the-right-slug to be redirected to /posts/12345/the-right-slug
The service is written in a universal fashion, so I can use it in any resourceful controller. I have't found a way to break it yet, but I'm open to correction.
Resources
Railscast #398: Service Objects by Ryan Bates
This Helpful Tweet by Jared Fine
I have a user that signs up and logs in.
Right now their route is rails standard "user/3".
A user belongs to an organization. An org has many users.
I want all users for that org, when they sign in, to have the url http://mysite.com/:organization name.
How would I accomplish this?
I'm not sure how your authentication is setup or what you're using to handle your authentication, but presumably when a user logs in successfully you just change the redirection in your log in action. Something like:
redirect_to user.organization
instead of redirect_to user
You need to browse on nested resources. Please look at http://guides.rubyonrails.org/routing.html#nested-resources
UPDATE: more appropriate answer
I think this is more for your scenario http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html#method-i-scope
You have to do something like this...
First add a method to your organization model to show name instead of id in url
def to_param
name
end
and update your routes as required, and functionality also to show the users of that organization
Organization Controller..
def show
#organization = Organization.find(params[:organization])
#users = #organization.users
end
Redirect user to user organization show path after login.
In my rails app, i have a create button as such
def create
#client = Client.find(params[:client_id])
#inventory = #client.inventories.create(params[:inventory])
redirect_to client_path(#client)
end
which when an inventory is created (as a part of client, ex. client has_many inventories, inventories belongs_to clients), the inventory is added to the client in the database and it redirects to localhost:3000/client/(whatever the clients ID is)
However, i'm having a problem with my program because although it does the correct redirect, the address in the address bar after i push create is localhost:3000/client/1/inventories/1... and I only want it to be localhost:3000/client/1/ . If I actually do try to access localhost:3000/client/1/inventories/1, it gives me an error because I don't have a show for inventories.
How is it possibly doing the correct redirect, but the wrong URL is displayed in my browser? By the way, this is in my routes.rb, which does not seem like the problem to me.
resources :clients do
resources :inventories
end
Why is my app behaving like this? Any takers? :]
EDIT
When I type rake routes I see this.
The routes for create and destroy seem wrong. How do I change them?
A workaround to this problem is going to inventories controller and adding
def index
#client = Client.find(params[:client_id])
redirect_to client_path(#client)
end
Looks like this was the best way to handle the back button hitting these errors, it seems like you cannot control the address displayed in the address bar. At least we don't know how.. :P
In this case, use:
redirect_to client_path(#client.id)