I'm using friendly_id 5.2.
By default, it just appends a random UUID on the end for what would be duplicate slugs (post-60948cdd-d73c-4b77-9676-ecdf7727c396), but with the sequentially_slugged method you can just turn it back to how it worked in version 4 where it appends a dash and then a number on the end (post-7).
What's the best way to replace the dash with a forward slash? post/7 (ordered by when they were created).
As far as I understand, you'd want to allow duplicate slugs in the gem and then just change the routes on Rails' end.
As I read in the documentation
Instance Attribute Summary
(Object) sequence_separator
The string used to separate a slug base from a numeric sequence.
(Object) slug_column
The column that will be used to store the generated slug.
(Object) slug_generator_class
Returns the value of attribute slug_generator_class.
Instance Attribute Details
(Object) sequence_separator
The string used to separate a slug base from a numeric sequence.
You can change the default separator by setting the sequence_separator configuration option.
Returns:
String The sequence separator string. Defaults to "-".
For a User model with columns :first_name and :last_name, what is the best way to write the full_name method. Both seem to work.
class User < ActiveRecord::Base
def full_name
first_name + last_name
end
end
Or
class User < ActiveRecord::Base
def full_name
self.first_name + self.last_name
end
end
I've looked at the SO posts below but am not sure
Why isn't self always needed in ruby / rails / activerecord?
This is because attributes/associations are actually
methods(getters/setters) and not local variables. When you state
"parent = value" Ruby assumes you want to assign the value to the
local variable parent.
Somewhere up the stack there's a setter method "def parent=" and to
call that you must use "self.parent = " to tell ruby that you actually
want to call a setter and not just set a local variable.
When it comes to getters Ruby looks to see if there's a local variable
first and if can't find it then it tries to find a method with the
same name which is why your getter method works without "self".
In other words it's not the fault of Rails, but it's how Ruby works
inherently."
Why isn't self always needed in ruby / rails / activerecord?
Why use “self” to access ActiveRecord/Rails model properties?
"Often the use of self is to force Ruby to recognize that as a method
call and not mis-interpret it as a variable. Without prior knowledge
of a method called day=, then day = "x" looks to Ruby like a variable
assignment. self.day = "x" is always a method call.
The reason this is trouble is because the name and name= methods are
added dynamically after the User class file has been parsed. The first
thing Rails does when using a model is make methods for the associated
database fields, but this happens after your user.rb file is parsed."
Why use "self" to access ActiveRecord/Rails model properties?
Camp 1: Convention over configuration. Also, self.first_name will not work for private accessors.
Camp 2: You know what's what at a glance, whereas you might forget what methods you have without the explicit receiver.
In the end, it's an opinion question, so I'm voting to close. However, food for thought:
bbatsov style guide:
Avoid self where not required. (It is only required when calling a self write accessor.)
GitHub style guide (based on bbatsov style guide):
Avoid explicit use of self as the recipient of internal class or instance messages unless to specify a method shadowed by a variable.
I am having some trouble understanding the syntax of variables and symbols in Ruby. I am reading a book called Agile Web Development with Rails 4. I am trying to learn both Ruby and Rails so that I can build websites.
The books and tutorials I have been reading sometimes have variables with the "#" symbol in front of them, and then some variables do not have the # symbol in front of them. What is the difference between them?
Also, I am getting confused with the colon. Sometimes I see variables where the colon is in the front, such as :order, and then I see variables where the colon is at the end, such as colon:. I do not understand what the colon is doing.
Please help me understand the Ruby syntax.
Variables starting with # are instance variables, "properties" in other languages. Whereas 'classic' variables are local to the scope of their method/block, instance variables are local to a specific instance of an object, for example:
class Foo
def initialize(bar)
#bar = bar
end
def bar
#bar # the variable is specific to this instance
end
def buzz
buzz = 'buzz' # this variable is not accessible outside of this method
end
end
You may also see variables starting with ##, which are class variables, and are accessible by every instance of the class and shared with every instance of the subclass. Usage of those variables is usually discouraged, primarily because subclasses share the variable, which can cause a lot of mess.
In Ruby everything is an object, classes are objects (instances of class Class), so you can also have class instance variables:
class Foo
def self.bar
#bar #we are in class Foo's scope, which is an instance of class Class
end
def self.bar=(bar)
#bar = bar
end
def bar
#bar # Foo.new.bar != Foo.bar
end
end
What you call "variables with a colon" are not variables. They are a particular type of string, called a symbol, that is immutable and optimized for quick identification by the interpreter, in fact, those are stored internally as pointers, so that :this == :this is a very quick operation.
This property makes them good candidates for hash keys because they offer quick retrieval or for "flags" to pass to a method; Think of them as a sort of loose constant that "stands for" what they say. Their immutability is also dangerous: All symbols ever created never get garbage collected; It's easy to create a memory-leak by creating thousands of symbols, so use them wisely.
UPDATE since ruby 2.2 symbols may be garbage-collected in certain cases (when no reference is kept and no comparison is needed)
Variables with an # symbol are instance variables. What this means is that they persist as long as the instance of the class they are declared in persists. So if you have a class called Message and each message has a variable called #subject, when you instantiate a new message it will keep that subject variable in memory as long as the message object itself lives. Now if it did not have the # symbol, once the function it was declared in "went out of scope" aka finished, the variable would be "lost" as the function was complete and the memory was reclaimed by the Ruby VM. There are also "class variables" that are prefaced with two # symbols. This means the variable is shared across all instances of a class.
As for the colon, if it is before a variable that means it is a "symbol", which is usually used as an identifer for hashes and other bits of data in Ruby. If it is at the end of a word that means it is the key portion of a hash identifier in Ruby 1.9+ syntax.
Instance Variables: (#foo = '123') An instance variable is defined and keeps its value throughout the current instance of the request. In the rails mvc paradigm, the most common use of instance variables are used to help communicate data from the controller to the view, and allows you ro define things in one part of the controller and use in another.
class ProjectsController < ApplicationController
before_filter :find_project
def show; end
def update
if #project.update_attributes(params[:project])
...
end
end
private
def find_project
#project = Project.find(params[:id])
end
end
In the above code, you can see that there is a before filter that gets ran before every method. In the above case, we find the current project and save it to an instance variable. And because its an instance method, its able to be access anywhere within this class as well as the views used to render the html.
Local Variables: (foo = '123') Pretty much exactly what the name implies, they are only able to be accessed within the current method (def) of where they are defined.
sometimes have variables with the "#" symbol in front of them, and then some variables do not have the # symbol in front of them.
Variables with the "#" symbol are instance variables,which are not preceded by #,can be constants or local variables or global variables. Read Ruby Programming/Syntax/Variables and Constants.
Sometimes I see variables where the colon is in the front, such as :order
They are called symbols.
and then I see variables where the colon is at the end, such as colon:. I do not understand what the colon is doing.
These probably the Hash syntax(as you give us hints,so I would guess),where keys are symbols. Example : {foo: 1} - this is a Hash.
Also read as you requested :
Normal Variables Vs Instance variable in Ruby, Whats the difference?
I have a simple active record query.
Product.active.select('stats_date, clicks_through')
I want to make clicks_through as a variable that will contain name of the attribute.
I tried
.select('stats_date, #{type_of_data}')
But this is not working. Any suggestions?
If type_of_data is a variable that holds a string or symbol that is a column in your database, the following should work (assuming that Product.active is a scope that returns an ActiveRecord::Relation).
Just change it to:
.select("stats_date, "#{type_of_data}")
(note the double quotes, which are required to use string interpolation in Ruby).
It's been almost 10 years, but there are some public methods available for this;
User.select(
User.sanitize_sql_array([':column', column: 'id'])
)
# "SELECT 'id' FROM \"users\"
It's basically that, you use the methods that ActiveRecord provides to sanitize the arguments for select.
Whether your query is prone to SQLi or not will depend entirely on the implementation of the sanitize_ methods.
In Rails, how do I go from a resource to a string containing its class name stylized with hyphens (as in a CSS class name)? I'd like a method #hyphenated_class_name or the like that I can apply to ActiveRecord resource of, say, class MyResource, and get back my-resource.
You're probably looking for underscore or dasherize methods, from ActiveSupport::Inflector. You need both to go from a class name to hyphenated string:
> PrettyPrint::SingleLine.name.demodulize.underscore.dasherize
=> "single-line"