I have looked around but I haven't really found an answer that seals the deal 100% for my individual situation.
In my Ruby app, I have a user share system where members can post 'stuff'. Well, sometimes members post links, and I have noticed as the site grows, more and more users are complaining about there not being clickable links.
How would I utilize regular expressions to match urls for links in posts. Furthermore, how would I apply this in my Model?
Thanks for you help, out of all my questions, this is a real important one for me ha!
EDIT
I suppose my init post was too vague...
I am more trying to figure out HOW to IMPLEMENT the use of regular expressions into my model instead of which regular expression to use.
The model is class Share. And the member's post is rendered as <%= share.content %> with content being a column in my Share table as well as an accessible attribute...
Thanks.
Try:
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
from the IETF Specification on URLS. It matches ALL URLS including "ftp://..." so you may need to tweak it somewhat.
autolink will do it. It's been extracted into it's own gem...
https://github.com/tenderlove/rails_autolink
Example usage:
auto_link("Go to http://www.rubyonrails.org and say hello to david#loudthinking.com")
# => "Go to http://www.rubyonrails.org and
# say hello to david#loudthinking.com"
Related
I'm building my first Ruby on Rails application, and I want to do it the "Rails" way, making my application as RESTful as possible.
The application revolves around a search function, in which a user fills out a form defining what they are looking for, submits it, then pages through their results, viewing items they are interested in. From my understanding of REST, it sounds like I should be encoding my parameters into the URL for my results page(?)
If my base route is:
match "search" => "search#index"
And the base route for my search results are:
match "search/results" => "search#results"
What would be the best way of implementing routes/URLs/parameters for my search? The solution must:
Support many parameters (30+), of which, any could be optional.
Support pagination: there could be alot of results.
Adhere to the "Rails way"!
Any suggestions/tips from you Rails pros would be very helpful, thanks!
For pagination: you can use a gem like will_paginate or kaminari
Concerning search parameters: Rails will put anything in the request's query string into a params variable accessible within your controllers and views.
What you're trying to do (naming the urls search & search/results) doesn't really align with "restful routes". Still, this is what you've asked for.
scope :search do
get 'search' => 'search#index'
get 'search/results' => 'search#show'
end
will produce
search GET /search(.:format) search#index
search_results GET /search/results(.:format) search#show
To remain restful, try discerning what you're searching for... for products, the results would be displayed using Products#index.
If you want to keep the search broad, I'd suggest Search#new and Results#index. These latter options seem more RESTful.
As you are probably anticipated, passing those 30 params around as url parameters is probably not the best approach.
I would consider creating a Configuration model (and table) for them and focus on the form being able to update this model. This will make storing the searches, doing multiple searches, validating the searches much easier in IMHO. Use this model in conjunction with the actual model, to do the searches.
For the pagination, as rthbound says use will_paginate or kaminari.
I'm pretty new at rails, so forgive me if I'm overlooking simple things or the rails way. My objective is to completely replace URLs of the form
/users/1
with
/username
for all purposes. (I think exposing IDs scaffolding publicly is like walking around with a bone sticking out of your arm.) But implementing seems a little more complicated than I expected. This seems to change the entire way rails indexes and looks up users, rather than just substituting a lookup method.
Although I've kind of gotten this to function using the to_param override in my user.rb file, I've read this means I'll have indexing problems down the road when using params([:username]), and I'm not sure how it will impact my
(a) session model at new user creation, and
(b) #User usage in the user/show.html.erb file.
So, I've either consulted the following pages (or asked the questions):
Ruby on rails routing matching username
customize rails url with username
Routing in Rails making the Username an URL:
routing error with :username in url
Correct routing for short url by username in Rails
rails3, clean url, friendly_id, sessions
The major issues I'd like to understand from this question:
What functionality do I lose by transitioning to this? That is, what things currently "just work" in rails that I'll have to address and rewrite if I pursue this replacement?
As a practice, is this something better to replace with friendly_id? My concern here is that creating a slug column in my DB identical to the username seems a little non-DRY and makes me uncomfortable, and I'd rather avoid dependencies on external gems where possible.
What does my users#show need to look like?
You should check out Friendly ID. Makes doing what you're trying to do incredibly easy.
https://github.com/norman/friendly_id
There's a Railscast for it, too.
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
If your username contains a special characters like #, -, . and got an error that says "No route matches" then you need to filter its route. See below:
match "/user/:username" => 'users#show', :as => :profile, :username => /[\.a-zA-Z0-9_#-]+/
After working around this for a couple weeks, I'd say the best answer as of Aug 2, 2012 is that if you do this, you violate many rails conventions and rip apart the very fabric of time and space itself.
Ugly scaffolding in the URLs is a necessary part of rails' approach to RESTfulness.
How has Github managed to get friendly URLs for representing repos of users? For a project called abc by username foo, how do they work around with a URL like: http://github.com/foo/abc. Are they fetching the abc model for the DB from the title in the URL (which sounds unreasonable as they are modifying the titles). How are they transferring the unique ID of the abc repo which they can fetch and show in the view?
The reason I ask is that I am facing a similar problem of creating friendlier URLs to view a resource. MongoDB's object IDs are quite long and make the URL look horrific. Is there a workaround? All the tutorials that demonstrate CRUD (or REST) URLs for a resource always include the object's unique ID(e.g. http://mysite.org/post/1 or http://mysite.org/post/1/edit. Is there a better way to do it?
Not having seen their code, I couldn't tell you exactly how they do it, but if you're using Rails there are at least two Ruby gems that will give you similar results:
Take a look at Slugged and friendly_id
http://github.com/foo/abc is a unique repository identifier (for that repo's master branch). I'd assume that somewhere they have a table that looks like:
repository-id | user-id | project-id
and are just looking up based on user and project rather than repository-id.
You'd need to do some domain-specific mapping between internal and user-friendly ids, but you'd need to make sure that was a 1:1 mapping.
See this rails cast on methods, gems and solutions to common problems you might get while modifying the application to use friendly urls.
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
(although Ryan Bates deserves the rep+ for this)
I mocked a structure like this using FriendlyID and Nested Resources.
Essentially, use friendly ID to get the to_param-ish slugs in your routes, then set up nested resources. Using GitHub as an example:
routes.rb
resources :users do
resources :repositories
end
Then in your controller, say, for repositories, you can check the existence of params[:user_id] and use that to determine the user from the route. The reason I check for existence is because I did something like (roughly):
/myrepositories/:repository_id
/:user_id/:repository_id
So my controller does:
def show
#user = params[:user_id] ? User.find(params[:user_id]) : current_user
end
I followed this tutorial here to get started with this same project.
This is called URL rewriting if the web server does it (such as Apache), and routing when it happens in a web application framework (such as Ruby on Rails).
http://www.sinatrarb.com/intro#Routes
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
I just started deploying a Rails website. In fact, I started programming on Rails 2 days ago.
I've created a new project, added some gems, etc. Everything is working properly, and I have some basic knowledge on how all works.
The thing is that what I want to create is a simple website with some sections (let's say, News, Contact, About, Products...). All this content is kinda static.
But I came in a problem. I don't really know what to do in order to create them. What I want, for example, is something like mypage.com/products/fashionableproduct, mypage.com/about, etc, or even mypage.com/page/products.
I thought about creating a Controller, then an action for each page... afterwards, I came up with other solution: scaffolding. Creating a resource called page, that has a title, etc...
I'm really a beginner on this topic, and I would like to hear your helpful voice.
Thanks!
Check out https://github.com/thoughtbot/high_voltage for static pages for Rails.
And check out http://railscasts.com/episodes/30-pretty-page-title for setting page titles.
The paths to your files are determined by your routes. The configuration file for routes is located at config/routes.rb. You can match a URL path, and then point to a given resource. More information about routes here: http://guides.rubyonrails.org/routing.html
If you generate a controller, you can process any dynamic data and then pass this data to these "kinda static" pages. Here is an example configuration that would match the path "mypage.com/about" and display the appropriate page:
# config/routes.rb
match "/about" => "example_controller#about"
# app/controllers/example_controller.rb
class ExampleController < ApplicationController
def about
# calculations
end
end
# app/views/example/about.html.erb
<!-- This is your HTML page -->
I think the title of your post might be a bit misleading. I have the feeling you don't want static pages but some database stored content. Just like Ben Simpson tells you to do, create a normal pages controller and make it work.
In the end you might want to customize some routes to get them to be exactly the way you want as in your examples.
Since you just started the app, I strongly recommend you start over and make a new app with Rails 3.1 which is the most current version and learn how to do the basics through http://guides.rubyonrails.org/ and a few other sources such as http://railscasts.com.
You will then learn Rails the right way from the beginning. Good luck and have fun in the process.
I'm basically putting together an app that does a super simple question => answer test in an attempt to learn more about rails.
ie:
Question: "What's your dog's name?"
Answer: "Doggington"
I have a Question model with two simple attributes:
question:string
correct_answer:string
My struggle here is how do i apply REST principals to this -- specifically, when i am checking a user's input(answer) to see if he got the question right or not.
I'm not sure if i should do something like modify the "show" method (or any other action) to accept values for answer posted to it... and it SEEMS like I should create a new method in my questions_controller called "verify_answer" or something a long those lines.
This breaks REST.
What do you think?
thanks!
AnswersController#create should accept the answers. Whether or not this controller actually has a related Answer model is irrelevant. One action should never perform two actions. For instance, if your QuestionsController#show both displays the question, and accepts a :put or :post with the answer to the question then you are breaking basic rails design principals.
Note that your routes file might very well look like this:
resources :questions do
resource :answer
end
Which will expose the /questions/8/answer route that you can :post to, which will go to AnswersController#create.
Off the top of my head I'm forgetting the exact name of the helper url method you can use to generate the url. Something like question_answer_path(#my_question).
This routing file is for rails3, which I assume is what you're using since there's no reason to use anything else if you're starting a new app in my opinion :p
If you do have an Answer model (maybe you want to store users' answers and look at them later or aggregate them and come up with statistics and such) then you should change the router to use resources :answer instead of the singular version.
For more information about routing and some RESTful tips you should visit the Ruby on Rails guide for routing found here: http://guides.rubyonrails.org/routing.html
I'm on an editing spree! There are times when you might need to add an additional method to your Questions controller that isn't strictly REST. This isn't necessarily considered bad practice but just make sure you look at your decisions and find out if you aren't actually just hiding the existence of another resource. I don't consider this to be one of those times as explained above :)