How can you make the id in the URL be random? - ruby

So I am looking for a way to create a randomized id that will link to a lobby that will be shown when the shown method is called in rails. As of right now, the url would look like this: http://localhost:3000/lobby/2. I'm looking to replace that 2 with a randomly generated id so you could send that link to friends if you want them to join your lobby. Any ideas?

You should share a bit more information as Gavin said. Knowing what you have already tried can help us give you more/better information on how to proceed.
I hope this sends you the right direction. For generating random IDs you can use SecureRandom:
http://ruby-doc.org/stdlib-1.9.3/libdoc/securerandom/rdoc/SecureRandom.html
I'd recommend you add another column to the lobbies table, and make it unique:
add_column :lobbies, :secure_token, :string, null: false
add_index :lobbies, :secure_token, unique: true
Now, in your Lobby model, whenever it is created, you can generate a unique token. For simplicity, you can do something along these lines:
class Lobby < ActiveRecord::Base
before_create :generate_unique_secure_token
# Rest of the model's code
private
def generate_unique_secure_token
begin
self.secure_token = SecureRandom.urlsafe_base64
end while self.class.exists?(secure_token: secure_token)
end
end
This will generate a secure_token every time a Lobby is created. Now in the controller you can use the secure_token instead of the id to find your Lobby. For example:
class LobbiesController < ApplicationController
def show
#lobby = Lobby.find_by(secure_token: params[:id])
end
end

I won't give you the whole answer since it's great to learn these things, but if you have any questions feel free to ask me!
This is where you should start: URLSafe Base 64
Here's a Railscasts episode that's soft of similar to what you want, see if you can expand from there! If you're new to Rails, be sure to check out Railscasts. All the pro episodes are available for free on youtube!

Related

Association Exclude Based on Field

I'm looking for the best Ruby way to accomplish this.
I have a Person that has_many Feeds through Subscriptions. So we can do things like Person.feeds, and it gets all the feeds a person is subscribed to.
Problem is, subscriptions are either authorized or deauthorized. What is the best way to make Person.feeds respect the Authorized status bit on the Subscription model?
So we can do something like Person.feeds.where(:status => authorized).
You can call this with a command like the following:
#person.feeds.joins(:subscription).where(subscriptions: { status: 'authorized' })
N.B. the joins takes the association's format, singular in this case, while where takes the table name, typically pluralised.
What this does in order is:
Loads the feeds belonging to a person
Joins these feeds to their subscription
Queries the subscriptions table to return only the feeds where the subscription is active
To refactor this, I'd include a couple of methods in the relevant models:
# feed.rb
scope :active, -> { joins(:subscription).where(subscriptions: { status: 'authorized' }) }
# person.rb
def active_feeds
feeds.active
end
Then, you can just call #person.active_feeds to get the results you want from anywhere in your code base.
(There's also the added bonus of Feed.active being available anywhere should you wish to display active feeds outside of a user's scope.)
Hope that helps - let me know if you've any questions.

changing value of activerecord attribute

I have a problem and I am not sure how can I resolve it...
lets say I have a class User < ActiveRecord::Base and I have attribute factor:int that is my database, and I can access this atribute with User.find(x).factor.
Now, I have another table where i have changed_attributes, but not for all users.
So I want to rewrite attribute factor: when there is an entry in changed_attributes with user id, User.factor would be new, and if not, old factor would be returned.
I know this works:
class User < ActiveRecord::Base
def factor
newfact=20
newfact
end
end
but I dont know how to access old factor variable?
thank you
Dorijan
edit:
I have found the solution: read_attribute(:factor)

Routes - how to display in url ID and the name of article?

I have the Articles controller and for displaying the respective article I use the basic routes - example.com/articles/4.
I would like to change this URL format to example.com/4-article-name or example.com/article-name-4.
Could anyone give me a tip, how to do that?
Thanks
Ryan Bates(Railscast.com) seems to have done an episode that solves your problem:
/app/models/article.rb
class Article < ActiveRecord::Base
def to_param
"#{id} #{name}".parameterize
end
end
See: http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
Generally numbers on the beginning is the most elegant way, since in ruby it could be very easily converted to integer, for instance '123-foo-bar'.to_i will return 123.
See http://apidock.com/rails/ActiveRecord/Base/to_param you'll find how to change this mechanism.

Trouble passing value from view to controller in Rails 3.1.1

I have two model Product and Category, they have has_many, and belongs_to association respectively. Now, what I am trying to do is when I click on particular category I want all the products of that category to be listed. How do I do that
here is my view
<p><%=link_to #product.category.name, show_by_category_products_path(#product.category.id)%> <%= #product.name%> <%=#product.category.id%><p>
and method in controller
def show_by_category
#products = Product.where("category_id=?", :id)
end
Thanks! (I know its simple stuff, but sometimes you get blind and can't see a straightforward way so you have to sought help of others)
EDIT
okay maybe I figured out a way to go around this.. but I am not sure if it is done in right way
Now my view and model looks something like this
<p><%=link_to #product.category.name, show_by_category_product_path(id: #product.id)%> <%= #product.name%>
def show_by_category
#prod = Product.find(params[:id])
#products = Product.where('category_id=?', #prod.category_id)
end
Tell me if this is right way?
Your find should look more like Category.find(params[:id]).products. But try to follow RESTful routing principles, and nest your resources. Rails will do much more for you.
I would recommend you to read at least Getting Started guide, because you are doing it wrong.

Rails 3. Leaving wrong value of integer attributes in a form

I have model 'Human' and this model has integer attribute :age.
For example, I use validation for this integer attribute :age.
When I add new 'Human' with wrong value of :age (e.g. "2aaa3") it is render me back with error, but it is also cut :age like "2". But I don't want it. I want to leave last wrong value "2aaa3".
So, question is "How can I do it?"
That is the default behaviour of validation in Rails. Not sure if there are any other ways to override it. You could however do that validation using javascript, which will be much more user experience oriented than using validates_numericality_of.
Hi everybody who is interested in my question.
I am glad to say I've created solution by myself.
But I have several remarks to that. ))
First, the solution is:
class ApplicationController < ActionController::Base
...
...
after_filter :restore_int_value, :only => [:create, :update]
...
...
private
...
...
def restore_int_value
response.body = response.body.gsub(/(numeric.*<input id=")([^_]*)(_)([^"]*)(.*value=")(\d+)(")/){$1 + $2 + $3 + $4 + $5 + params[$2][$4] + $7}
end
...
...
end
Second, remarks are:
1) the solution works along such gems as 'Formtastic' and 'Simple_form'. These gems build the forms wraped in detailed html and give us possibility to use regex.
If you don't use such gems you can just wrap all your integer attributes, for example, in 'p' tag with 'numeric' class like following and I think my solution will work for this too:
<p class="numeric"> <%= text_field(:human, :age) %> </p>
2) I think my solution will not work for integer fields of nested models in multiple-models-form. (Ryan Bates describes such kind of work in "Handle Multiple Models in One Form" from "Advanced Rails Recipes").
But if you read Ryan Bates' article you will see that he already uses JavaScript. So, working with nested models in form you need JavaScript. Then you can use JavaScript for validation too (as Kunday told). And you will not have a problem. ;)
But if you have static number of nested models in form and do not use JavaScript, then I think you can create new particular regex for your needs (similar to the one I created). I hope you will manage with this. ;)
I hope I've covered all scenarios where you can have such problem and my solution will be useful for somebody, besides me. ;)

Resources